Compare commits
193 Commits
v4.5.2-252
...
v4.6.1-271
| Author | SHA1 | Date | |
|---|---|---|---|
| 7684c247bf | |||
| f2b9d26e8a | |||
| 338de605ec | |||
| 591a694bdf | |||
| 9fd9a4ebcc | |||
| f2712c3db7 | |||
| 61c2c7b218 | |||
| 8a54c47d9e | |||
| 7ec4ba6582 | |||
| bebdbe64cd | |||
| a0555d6ffc | |||
| 9cf852b490 | |||
| a232ef9d03 | |||
| 05b90bd5b4 | |||
| 4a31f74dcb | |||
| 79cf96b161 | |||
| 7fdd4dbf04 | |||
| 8eeeb5de60 | |||
| c540c14e1c | |||
| bc6786b21e | |||
| db4b049591 | |||
| 86db2b5688 | |||
| be3a3e82af | |||
| fc476ca889 | |||
| fc36ce6a03 | |||
| 0a1d330c2f | |||
| e5ec42576c | |||
| b57f74a411 | |||
| 0cb3184e35 | |||
| 76c5009fbc | |||
| 312ec153f1 | |||
| 1ef79df4c5 | |||
| d7a809f8a6 | |||
| ebadeeb873 | |||
| 55155ee8ae | |||
| be98a6b6d6 | |||
| e2f396f8c7 | |||
| d6adda78c4 | |||
| 99708d7801 | |||
| 584986a9d5 | |||
| 507da05841 | |||
| 72a8fe4764 | |||
| f9f23f6324 | |||
| e2964f93c7 | |||
| cb2a9a3ca0 | |||
| ea68941bb9 | |||
| b598d331d4 | |||
| d7b876bfed | |||
| 6aca60080a | |||
| 59d76688b9 | |||
| 8e5e677228 | |||
| dd1bfcaddd | |||
| f4c66e1ab7 | |||
| 6ebdf6e42a | |||
| 4c01dd442b | |||
| ac226e3301 | |||
| 569f1b8cf1 | |||
| 46f5da88a6 | |||
| f5b876b018 | |||
| c5df856023 | |||
| 4f775847dc | |||
| f53710fdf5 | |||
| 80c56def08 | |||
| a1d88d999e | |||
| fbc6f6adaa | |||
| e7c55b2467 | |||
| 2c45bb1da9 | |||
| 173825dc74 | |||
| a63e28809b | |||
| 0eb8cb6e66 | |||
| e1514e2b25 | |||
| bef0da821b | |||
| 54741729f3 | |||
| e2640c22f8 | |||
| 2f16d5ba99 | |||
| 1d5301f887 | |||
| cc09c702f7 | |||
| 6b2a88766e | |||
| 0eb629fe67 | |||
| 44c398c9fb | |||
| 96122c5919 | |||
| bd4c438036 | |||
| adc8648f5a | |||
| 8eb3922a33 | |||
| 30743bb015 | |||
| 853f51ad0e | |||
| 763aad99ee | |||
| 2ed2317b02 | |||
| 0663f3eb2b | |||
| 11a2eeae7a | |||
| 8c2619bb22 | |||
| 46320fe07d | |||
| 1ee933b115 | |||
| 1d9152ca1a | |||
| 81ebf21bb9 | |||
| dd4bf98f28 | |||
| ba3a06da43 | |||
| 6fe096383c | |||
| d16f99958f | |||
| 5fa3aa42dc | |||
| f4f28a2daa | |||
| 3c1cd14bdc | |||
| 6dcc251312 | |||
| f692aa4bff | |||
| 7cde55ebe0 | |||
| 94eba08af4 | |||
| 2bf207661c | |||
| 2fff7f60c2 | |||
| 1b3c93ebb5 | |||
| 5b529b044e | |||
| 91f417f479 | |||
| fc0bf595bd | |||
| c0f6499577 | |||
| b9bef384f1 | |||
| 58bfae2fdb | |||
| d2c2fff884 | |||
| ab178c47b5 | |||
| 40be004376 | |||
| 0b501c9ce1 | |||
| cff82379f5 | |||
| 825503bd58 | |||
| 77a715a4bd | |||
| 78b233c506 | |||
| a6e799bb9a | |||
| b65992099a | |||
| 3d1a5f52bf | |||
| 82d0d5745c | |||
| fe7968cb32 | |||
| 94c503af74 | |||
| bdd9815ffc | |||
| 693acceca8 | |||
| 90971bc299 | |||
| e5b3613348 | |||
| 652ca8f69c | |||
| f15e351c1e | |||
| 47c81c3dac | |||
| 7453a61e4f | |||
| 911f6397e8 | |||
| 8d21a4f774 | |||
| 991c54b680 | |||
| 48dcb5089b | |||
| 461efe7101 | |||
| 0735161a20 | |||
| 093c1e2b15 | |||
| 7d0e02c899 | |||
| 8294913f04 | |||
| e811c4f90b | |||
| 69e248b389 | |||
| 43f6bfc4c2 | |||
| c8b81ab56a | |||
| aa41fd98e8 | |||
| ff6c4c2de9 | |||
| 136761d2f7 | |||
| 9374fc5264 | |||
| 324aaa5056 | |||
| f22afbd819 | |||
| e149231cb2 | |||
| 9c8155ddf8 | |||
| dd95419a36 | |||
| 870b10dd13 | |||
| 637b426649 | |||
| ee8ce87e28 | |||
| a944a7f730 | |||
| fdbb16b45f | |||
| 29bc098dcf | |||
| b2433cf13a | |||
| e908e23bb2 | |||
| 1a4dc827b5 | |||
| 9fd5e65fa2 | |||
| 5405dcd30e | |||
| 5c35f7fe5d | |||
| fc907a398f | |||
| 1b8dc6eba0 | |||
| c17a36c866 | |||
| a29cf832f1 | |||
| c9a628a5e9 | |||
| 165ba01afd | |||
| a39a8c2cce | |||
| 4002f138bb | |||
| 48fdb38902 | |||
| 38a3120ea1 | |||
| c0e370dfd2 | |||
| e4765089fa | |||
| 721e73ca1e | |||
| e406c90027 | |||
| e7c4886219 | |||
| 80a2e4f336 | |||
| 9f5940c6f6 | |||
| d01fda44b3 | |||
| 2020033bc0 | |||
| dc2c8e590c | |||
| b115db51e9 | |||
| 7d194c7078 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,5 +7,6 @@ local.properties
|
||||
captures/
|
||||
build/
|
||||
release-app/
|
||||
test-app/
|
||||
scripts/apk-channel/
|
||||
app/src/test/java/com/gh/gamecenter
|
||||
@ -38,6 +38,10 @@ android {
|
||||
javaMaxHeapSize "4g"
|
||||
}
|
||||
|
||||
aaptOptions {
|
||||
additionalParameters "--no-version-vectors"
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
|
||||
multiDexEnabled true
|
||||
@ -328,7 +332,7 @@ dependencies {
|
||||
implementation "com.ethanhua:skeleton:${skeleton}"
|
||||
implementation "io.supercharge:shimmerlayout:${shimmerlayout}"
|
||||
implementation "com.tencent.mm.opensdk:wechat-sdk-android-without-mta:${mta}"
|
||||
implementation "com.walkud.rom.checker:RomChecker:${romChecker}"
|
||||
implementation "com.github.nichbar:AndroidRomChecker:${romChecker}"
|
||||
|
||||
debugImplementation "com.github.nichbar.chucker:library:$chucker"
|
||||
releaseImplementation "com.github.nichbar.chucker:library-no-op:$chucker"
|
||||
|
||||
@ -31,6 +31,8 @@ object GdtHelper {
|
||||
GDTAction.init(application, "1111012969", "9d3d9da5b0948a317c03d08f14d445dc")
|
||||
} else if (channel == "GH_729") {
|
||||
GDTAction.init(application, "1111013063", "f53dabf458a356b101d99fc4069eb7f1")
|
||||
} else if (channel == "GH_765") {
|
||||
GDTAction.init(application, "1111327925", "588d503f0990f98f9b2394fbb795c570")
|
||||
} else {
|
||||
GDTAction.init(application, "1110680399", "f5ddaafbf520d7d7385499232a408d0a")
|
||||
}
|
||||
|
||||
@ -603,6 +603,18 @@
|
||||
android:name=".forum.search.ForumOrUserSearchActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".energy.EnergyCenterActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".energy.EnergyHouseActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".personal.NewPersonalActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- <!– 使用小米/华为推送弹窗功能提高推送成功率–>-->
|
||||
<!-- <activity-->
|
||||
<!-- android:name="com.gh.gamecenter.PushProxyActivity"-->
|
||||
|
||||
@ -25,6 +25,7 @@ import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import io.sentry.core.Sentry;
|
||||
|
||||
@ -38,19 +39,21 @@ public class AppUncaughtHandler implements UncaughtExceptionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread thread, Throwable ex) {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
if (("FinalizerWatchdogDaemon").equals(t.getName())
|
||||
&& e instanceof TimeoutException) {
|
||||
// ignore timeoutException
|
||||
// detail can be found in this didi tech blog post https://mp.weixin.qq.com/s?__biz=MzU1ODEzNjI2NA==&mid=2247487185&idx=2&sn=cf2d9e10053f625bde0f61d246f14870&source=41#wechat_redirect
|
||||
} else {
|
||||
new Thread(() -> {
|
||||
Looper.prepare();
|
||||
Utils.toast(mContext.getApplicationContext(), "\"光环助手\"发生错误");
|
||||
Looper.loop();
|
||||
}
|
||||
});
|
||||
|
||||
saveLocalLog(mContext, ex);
|
||||
Sentry.captureException(ex);
|
||||
restart(mContext);
|
||||
});
|
||||
saveLocalLog(mContext, e);
|
||||
restart(mContext);
|
||||
Sentry.captureException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void restart(final Context context) {
|
||||
|
||||
@ -72,6 +72,7 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
public final static String DOWNLOAD_HIJACK = "hijack";
|
||||
public final static String LOGIN_EXCEPTION = "loginException";
|
||||
public final static String PLUGGABLE = "plugin";
|
||||
public final static int ID_ROOT_INDICATOR = 999;
|
||||
|
||||
@NonNull
|
||||
protected String mEntrance;
|
||||
@ -206,6 +207,7 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13);
|
||||
tv.measure(0, 0);
|
||||
tv.setAlpha(0.15F);
|
||||
tv.setId(ID_ROOT_INDICATOR);
|
||||
int height = tv.getMeasuredHeight();
|
||||
int width = tv.getMeasuredWidth();
|
||||
tv.setPadding(DisplayUtils.dip2px(20), 0, DisplayUtils.dip2px(20), 0);
|
||||
|
||||
@ -9,15 +9,18 @@ import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.webkit.JavascriptInterface
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import butterknife.OnClick
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.MtaHelper
|
||||
import com.gh.common.AppExecutor
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.view.RichEditor
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.MyVideoEntity
|
||||
import com.gh.gamecenter.qa.answer.edit.AnswerEditActivity
|
||||
import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
|
||||
import com.gh.gamecenter.qa.editor.GameActivity
|
||||
import com.gh.gamecenter.qa.editor.InsertAnswerWrapperActivity
|
||||
import com.gh.gamecenter.qa.editor.InsertArticleWrapperActivity
|
||||
@ -26,6 +29,7 @@ import com.gh.gamecenter.qa.entity.AnswerEntity
|
||||
import com.gh.gamecenter.qa.entity.ArticleEntity
|
||||
import com.gh.gamecenter.qa.entity.EditorInsertEntity
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.lightgame.utils.Utils
|
||||
import com.lightgame.view.CheckableImageView
|
||||
import kotterknife.bindView
|
||||
@ -33,15 +37,15 @@ import kotterknife.bindView
|
||||
abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
|
||||
val mRichEditor by bindView<RichEditor>(R.id.rich_editor)
|
||||
val mDraftBtn by bindView<TextView>(R.id.draft_btn)
|
||||
|
||||
private val mEditorTextNumTv by bindView<TextView>(R.id.editorTextNumTv)
|
||||
private val mEditorFont by bindView<CheckableImageView>(R.id.editor_font)
|
||||
private val mEditorLink by bindView<CheckableImageView>(R.id.editor_link)
|
||||
private val mEditorParagraph by bindView<CheckableImageView>(R.id.editor_paragraph)
|
||||
|
||||
private val mEditorFontBold by bindView<CheckableImageView>(R.id.editor_font_bold)
|
||||
private val mEditorFontItalic by bindView<CheckableImageView>(R.id.editor_font_italic)
|
||||
private val mEditorFontStrikeThrough by bindView<CheckableImageView>(R.id.editor_font_strikethrough)
|
||||
private val mEditorFontUnderline by bindView<CheckableImageView>(R.id.editor_font_underline)
|
||||
private val mEditorParagraphH1 by bindView<CheckableImageView>(R.id.editor_paragraph_h1)
|
||||
private val mEditorParagraphH2 by bindView<CheckableImageView>(R.id.editor_paragraph_h2)
|
||||
private val mEditorParagraphH3 by bindView<CheckableImageView>(R.id.editor_paragraph_h3)
|
||||
@ -50,9 +54,15 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
private val mEditorFontContainer by bindView<View>(R.id.editor_font_container)
|
||||
private val mEditorParagraphContainer by bindView<View>(R.id.editor_paragraph_container)
|
||||
private val mEditorLinkContainer by bindView<View>(R.id.editor_link_container)
|
||||
private val mEditorInsertDetail by bindView<View>(R.id.editor_insert_detail)
|
||||
private val mEditorInsertDetailContainer by bindView<View>(R.id.editor_insert_detail_container)
|
||||
val mAddLabelContainer by bindView<View>(R.id.add_label_container)
|
||||
val mAddLabelTv by bindView<TextView>(R.id.add_label_tv)
|
||||
val mLabelNumTv by bindView<TextView>(R.id.label_num_tv)
|
||||
val mLabelArrowIv by bindView<ImageView>(R.id.label_arrow)
|
||||
val mTagsContainer by bindView<FrameLayout>(R.id.tagsContainer)
|
||||
|
||||
private var mCurrentParagraphStyle = ""
|
||||
private var mIsExtendedKeyboardShow = false
|
||||
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
@ -63,29 +73,50 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
when (requestCode) {
|
||||
INSERT_ANSWER_CODE -> {
|
||||
val answer = data?.getParcelableExtra<AnswerEntity>(AnswerEntity::class.java.simpleName)
|
||||
if (answer != null) insertData = EditorInsertEntity.transform(answer)
|
||||
if (answer != null) {
|
||||
mRichEditor.focusEditor()
|
||||
insertData = EditorInsertEntity.transform(answer)
|
||||
mRichEditor.insertCustomStyleLink(insertData)
|
||||
}
|
||||
}
|
||||
INSERT_ARTICLE_CODE -> {
|
||||
val article = data?.getParcelableExtra<ArticleEntity>(ArticleEntity::class.java.simpleName)
|
||||
if (article != null) insertData = EditorInsertEntity.transform(article)
|
||||
if (article != null) {
|
||||
mRichEditor.focusEditor()
|
||||
insertData = EditorInsertEntity.transform(article)
|
||||
mRichEditor.insertCustomStyleLink(insertData)
|
||||
}
|
||||
}
|
||||
INSERT_GAME_CODE -> {
|
||||
val game = data?.getParcelableExtra<GameEntity>(GameEntity::class.java.simpleName)
|
||||
if (game != null) insertData = EditorInsertEntity.transform(game)
|
||||
if (game != null) {
|
||||
mRichEditor.focusEditor()
|
||||
insertData = EditorInsertEntity.transform(game)
|
||||
mRichEditor.insertCustomStyleLink(insertData)
|
||||
}
|
||||
}
|
||||
VideoActivity.INSERT_VIDEO_CODE -> {
|
||||
val video = data?.getParcelableExtra<MyVideoEntity>(MyVideoEntity::class.java.simpleName)
|
||||
if (video != null) mRichEditor.insertCustomVideo(video)
|
||||
return
|
||||
if (video != null) {
|
||||
mRichEditor.focusEditor()
|
||||
mRichEditor.insertCustomVideo(video)
|
||||
}
|
||||
}
|
||||
}
|
||||
closeExtendedKeyboard()
|
||||
AppExecutor.uiExecutor.executeWithDelay(Runnable {
|
||||
Util_System_Keyboard.showSoftKeyboard(this)
|
||||
}, 100)
|
||||
AppExecutor.uiExecutor.executeWithDelay(Runnable {
|
||||
mRichEditor.scrollTo(0, 1000000)
|
||||
}, 500)
|
||||
|
||||
mRichEditor.insertCustomStyleLink(insertData)
|
||||
}
|
||||
|
||||
@SuppressLint("AddJavascriptInterface")
|
||||
@SuppressLint("AddJavascriptInterface", "ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
mAddLabelContainer.visibility = if (this is ArticleEditActivity) View.VISIBLE else View.GONE
|
||||
mRichEditor.setPadding(20, 15, 20, 15)
|
||||
// 防止个别手机在Js里无法获取粘贴内容
|
||||
mRichEditor.addJavascriptInterface(OnPasteListener(), "onPasteListener")
|
||||
@ -93,12 +124,59 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
mRichEditor.addJavascriptInterface(OnEditorTextChangeListener(), "OnEditorTextChangeListener")
|
||||
mRichEditor.setInputEnabled(true)
|
||||
|
||||
mDraftBtn.text = if (this is AnswerEditActivity) {
|
||||
"回答草稿"
|
||||
} else "帖子草稿"
|
||||
mRichEditor.setOnTouchListener { _, _ ->
|
||||
if (mIsExtendedKeyboardShow) {
|
||||
closeExtendedKeyboard()
|
||||
Util_System_Keyboard.showSoftKeyboard(this)
|
||||
//是否消费事件根据mRichEditor是否含有焦点决定,mRichEditor没有焦点则不消费事件
|
||||
mRichEditor.hasFocus()
|
||||
} else false
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.editor_image, R.id.editor_font, R.id.editor_link, R.id.editor_paragraph,
|
||||
|
||||
fun closeExtendedKeyboard() {
|
||||
mEditorInsertDetailContainer.visibility = View.GONE
|
||||
mEditorFont.isChecked = false
|
||||
mEditorLink.isChecked = false
|
||||
mAddLabelContainer.isSelected = false
|
||||
mIsExtendedKeyboardShow = false
|
||||
}
|
||||
|
||||
protected fun controlEditorInsertContainerEnabled(isEnabled: Boolean) {
|
||||
mEditorFont.isEnabled = isEnabled
|
||||
}
|
||||
|
||||
fun changeAddLabel(isLabelContainerShow: Boolean) {
|
||||
if (isLabelContainerShow) {
|
||||
mLabelNumTv.visibility = View.GONE
|
||||
mLabelArrowIv.visibility = View.VISIBLE
|
||||
mAddLabelTv.setTextColor(ContextCompat.getColor(this, R.color.theme_font))
|
||||
mAddLabelTv.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
|
||||
mAddLabelContainer.background = ContextCompat.getDrawable(this, R.drawable.bg_editor_insert_add_label)
|
||||
} else {
|
||||
val selectedLabel = getSelectedLabel()
|
||||
if (selectedLabel == 0) {
|
||||
mAddLabelTv.text = "添加标签"
|
||||
mLabelNumTv.visibility = View.GONE
|
||||
mAddLabelTv.setTextColor(ContextCompat.getColor(this, R.color.text_666666))
|
||||
mAddLabelTv.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(this, R.drawable.ic_add_label), null, null, null)
|
||||
} else {
|
||||
mAddLabelTv.text = "标签"
|
||||
mLabelNumTv.visibility = View.VISIBLE
|
||||
mLabelNumTv.text = selectedLabel.toString()
|
||||
mAddLabelTv.setTextColor(ContextCompat.getColor(this, R.color.theme_font))
|
||||
mAddLabelTv.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
|
||||
}
|
||||
mLabelArrowIv.visibility = View.GONE
|
||||
mAddLabelContainer.background = ContextCompat.getDrawable(this, R.drawable.border_round_stroke_eee_999)
|
||||
}
|
||||
}
|
||||
|
||||
open fun getSelectedLabel(): Int = 0
|
||||
|
||||
|
||||
@OnClick(R.id.editor_image, R.id.editor_font, R.id.editor_link, R.id.add_label_container, R.id.editor_font_underline,
|
||||
R.id.editor_font_bold, R.id.editor_font_italic, R.id.editor_font_strikethrough,
|
||||
R.id.editor_paragraph_h1, R.id.editor_paragraph_h2, R.id.editor_paragraph_h3,
|
||||
R.id.editor_paragraph_h4, R.id.editor_font_container, R.id.editor_paragraph_container,
|
||||
@ -107,31 +185,13 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
fun onRichClick(view: View) {
|
||||
when (view.id) {
|
||||
R.id.editor_font -> {
|
||||
mEditorFont.isChecked = !mEditorFont.isChecked
|
||||
mEditorParagraph.isChecked = false
|
||||
mEditorLink.isChecked = false
|
||||
mEditorFontContainer.visibility = if (mEditorFont.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorParagraphContainer.visibility = if (!mEditorFont.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorLinkContainer.visibility = if (!mEditorFont.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorInsertDetail.visibility = mEditorFontContainer.visibility
|
||||
}
|
||||
R.id.editor_paragraph -> {
|
||||
mEditorParagraph.isChecked = !mEditorParagraph.isChecked
|
||||
mEditorFont.isChecked = false
|
||||
mEditorLink.isChecked = false
|
||||
mEditorParagraphContainer.visibility = if (mEditorParagraph.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorFontContainer.visibility = if (!mEditorParagraph.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorLinkContainer.visibility = if (!mEditorParagraph.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorInsertDetail.visibility = mEditorParagraphContainer.visibility
|
||||
controlEditorFontContainer()
|
||||
}
|
||||
R.id.editor_link -> {
|
||||
mEditorLink.isChecked = !mEditorLink.isChecked
|
||||
mEditorFont.isChecked = false
|
||||
mEditorParagraph.isChecked = false
|
||||
mEditorLinkContainer.visibility = if (mEditorLink.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorParagraphContainer.visibility = if (!mEditorLink.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorFontContainer.visibility = if (!mEditorLink.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorInsertDetail.visibility = mEditorLinkContainer.visibility
|
||||
controlEditorLinkContainer()
|
||||
}
|
||||
R.id.add_label_container -> {
|
||||
controlAddLabelContainer()
|
||||
}
|
||||
R.id.editor_font_bold -> {
|
||||
mEditorFontBold.isChecked = !mEditorFontBold.isChecked
|
||||
@ -155,6 +215,14 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
MtaHelper.onEvent(mtaEventName(), "文字样式", "文字样式-删除线")
|
||||
}
|
||||
}
|
||||
R.id.editor_font_underline -> {
|
||||
mEditorFontUnderline.isChecked = !mEditorFontUnderline.isChecked
|
||||
mRichEditor.setUnderline()
|
||||
|
||||
if (mEditorFontUnderline.isChecked) {
|
||||
MtaHelper.onEvent(mtaEventName(), "文字样式", "文字样式-下滑线")
|
||||
}
|
||||
}
|
||||
R.id.editor_paragraph_h1 -> {
|
||||
if (mEditorParagraphH1.isChecked) {
|
||||
mRichEditor.formatBlock()
|
||||
@ -213,12 +281,93 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
startActivityForResult(GameActivity.getIntent(this, GameActivity.INSERT_GAME_TITLE), INSERT_GAME_CODE)
|
||||
}
|
||||
R.id.editor_link_video -> {
|
||||
MtaHelper.onEvent(mtaEventName(), "插入链接", "插入链接-视频")
|
||||
startActivityForResult(VideoActivity.getIntent(this), VideoActivity.INSERT_VIDEO_CODE)
|
||||
PermissionHelper.checkStoragePermissionBeforeAction(this,
|
||||
object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
MtaHelper.onEvent(mtaEventName(), "插入链接", "插入链接-视频")
|
||||
startActivityForResult(VideoActivity.getIntent(this@BaseRichEditorActivity), VideoActivity.INSERT_VIDEO_CODE)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun controlEditorFontContainer() {
|
||||
mEditorFont.isChecked = !mEditorFont.isChecked
|
||||
mEditorLink.isChecked = false
|
||||
mAddLabelContainer.isSelected = false
|
||||
val isShouldDelay = if (mEditorFont.isChecked) {
|
||||
Util_System_Keyboard.hideSoftKeyboard(this)
|
||||
true
|
||||
} else {
|
||||
Util_System_Keyboard.showSoftKeyboard(this)
|
||||
false
|
||||
}
|
||||
mEditorInsertDetailContainer.postDelayed({
|
||||
mEditorInsertDetailContainer.visibility = if (mEditorFont.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorFontContainer.visibility = if (mEditorFont.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorParagraphContainer.visibility = if (mEditorFont.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorLinkContainer.visibility = View.GONE
|
||||
mTagsContainer.visibility = View.GONE
|
||||
mIsExtendedKeyboardShow = mEditorFont.isChecked
|
||||
changeAddLabel(false)
|
||||
}, if (isShouldDelay) 200 else 0L)
|
||||
}
|
||||
|
||||
private fun controlEditorLinkContainer() {
|
||||
mEditorLink.isChecked = !mEditorLink.isChecked
|
||||
mEditorFont.isChecked = false
|
||||
mAddLabelContainer.isSelected = false
|
||||
val isShouldDelay = if (mEditorLink.isChecked) {
|
||||
Util_System_Keyboard.hideSoftKeyboard(this)
|
||||
true
|
||||
} else {
|
||||
Util_System_Keyboard.showSoftKeyboard(this)
|
||||
false
|
||||
}
|
||||
mEditorInsertDetailContainer.postDelayed({
|
||||
mEditorInsertDetailContainer.visibility = if (mEditorLink.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorLinkContainer.visibility = if (mEditorLink.isChecked) View.VISIBLE else View.GONE
|
||||
mEditorFontContainer.visibility = View.GONE
|
||||
mEditorParagraphContainer.visibility = View.GONE
|
||||
mTagsContainer.visibility = View.GONE
|
||||
mIsExtendedKeyboardShow = mEditorLink.isChecked
|
||||
changeAddLabel(false)
|
||||
}, if (isShouldDelay) 200 else 0L)
|
||||
}
|
||||
|
||||
fun controlAddLabelContainer() {
|
||||
mEditorLink.isChecked = false
|
||||
mEditorFont.isChecked = false
|
||||
mAddLabelContainer.isSelected = !mAddLabelContainer.isSelected
|
||||
val isShouldDelay = if (mAddLabelContainer.isSelected) {
|
||||
Util_System_Keyboard.hideSoftKeyboard(this)
|
||||
changeAddLabel(true)
|
||||
true
|
||||
} else {
|
||||
Util_System_Keyboard.showSoftKeyboard(this)
|
||||
changeAddLabel(false)
|
||||
false
|
||||
}
|
||||
mEditorInsertDetailContainer.postDelayed({
|
||||
mEditorInsertDetailContainer.visibility = if (mAddLabelContainer.isSelected) View.VISIBLE else View.GONE
|
||||
mTagsContainer.visibility = if (mAddLabelContainer.isSelected) View.VISIBLE else View.GONE
|
||||
mEditorLinkContainer.visibility = View.GONE
|
||||
mEditorFontContainer.visibility = View.GONE
|
||||
mEditorParagraphContainer.visibility = View.GONE
|
||||
mIsExtendedKeyboardShow = mAddLabelContainer.isSelected
|
||||
}, if (isShouldDelay) 200 else 0L)
|
||||
}
|
||||
|
||||
override fun handleBackPressed(): Boolean {
|
||||
if (mIsExtendedKeyboardShow) {
|
||||
closeExtendedKeyboard()
|
||||
return true
|
||||
}
|
||||
return super.handleBackPressed()
|
||||
}
|
||||
|
||||
|
||||
private inner class OnCursorChangeListener {
|
||||
@JavascriptInterface
|
||||
fun onElements(elements: String) {
|
||||
@ -237,6 +386,7 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
mEditorFontBold.isChecked = elements.contains(ELEMENT_NAME_BOLD)
|
||||
mEditorFontItalic.isChecked = elements.contains(ELEMENT_NAME_ITALIC)
|
||||
mEditorFontStrikeThrough.isChecked = elements.contains(ELEMENT_NAME_STRIKE)
|
||||
mEditorFontUnderline.isChecked = elements.contains(ELEMENT_NAME_UNDERLINE)
|
||||
mEditorParagraphH1.isChecked = elements.contains(ELEMENT_PARAGRAPH_H1)
|
||||
mEditorParagraphH2.isChecked = elements.contains(ELEMENT_PARAGRAPH_H2)
|
||||
mEditorParagraphH3.isChecked = elements.contains(ELEMENT_PARAGRAPH_H3)
|
||||
@ -264,7 +414,9 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
@JavascriptInterface
|
||||
fun onTextChange(count: Int) {
|
||||
val num = if (count > MAX_INPUT_TEXT_NUM) MAX_INPUT_TEXT_NUM - count else count
|
||||
mEditorTextNumTv.text = num.toString()
|
||||
mEditorTextNumTv.post {
|
||||
mEditorTextNumTv.text = num.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,6 +426,7 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
const val ELEMENT_NAME_BOLD = " b "
|
||||
const val ELEMENT_NAME_ITALIC = " i "
|
||||
const val ELEMENT_NAME_STRIKE = " strike "
|
||||
const val ELEMENT_NAME_UNDERLINE = " u "
|
||||
const val ELEMENT_PARAGRAPH_H1 = " h1 "
|
||||
const val ELEMENT_PARAGRAPH_H2 = " h2 "
|
||||
const val ELEMENT_PARAGRAPH_H3 = " h3 "
|
||||
|
||||
@ -9,6 +9,8 @@ import com.gh.gamecenter.R;
|
||||
import com.lightgame.utils.RuntimeUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
@ -71,7 +73,22 @@ public class BaseDialogFragment extends DialogFragment {
|
||||
transaction.show(fragment);
|
||||
transaction.commit();
|
||||
} else {
|
||||
super.show(manager, tag);
|
||||
try {
|
||||
Class<?> clazz = DialogFragment.class;
|
||||
Field dismissed = clazz.getDeclaredField("mDismissed");
|
||||
dismissed.setAccessible(true);
|
||||
dismissed.set(this, false);
|
||||
|
||||
Field shownByMe = clazz.getDeclaredField("mShownByMe");
|
||||
shownByMe.setAccessible(true);
|
||||
shownByMe.set(this, true);
|
||||
FragmentTransaction transaction = manager.beginTransaction();
|
||||
transaction.add(this, tag);
|
||||
transaction.commitAllowingStateLoss();
|
||||
} catch (Exception e) {
|
||||
super.show(manager, tag);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.gh.common.util.ExtensionsKt;
|
||||
import com.gh.gamecenter.R;
|
||||
|
||||
/**
|
||||
@ -87,7 +88,11 @@ public class WaitingDialogFragment extends BaseDialogFragment {
|
||||
@Override
|
||||
public void dismissAllowingStateLoss() {
|
||||
mBackListener = null;
|
||||
super.dismissAllowingStateLoss();
|
||||
try {
|
||||
super.dismissAllowingStateLoss();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static class WaitingDialogData {
|
||||
|
||||
@ -17,6 +17,8 @@ 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.energy.EnergyCenterActivity
|
||||
import com.gh.gamecenter.energy.EnergyHouseActivity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
@ -115,6 +117,7 @@ class DefaultJsApi(var context: Context) {
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
EnergyTaskHelper.postEnergyTask("bind_wechat")
|
||||
handler.complete(true)
|
||||
}
|
||||
|
||||
@ -198,6 +201,7 @@ class DefaultJsApi(var context: Context) {
|
||||
@JavascriptInterface
|
||||
fun updateRegulationTestStatus(msg: Any) {
|
||||
if (msg.toString().toLowerCase(Locale.getDefault()) == "pass") {
|
||||
EnergyTaskHelper.postEnergyTask("finish_etiquette_exam")
|
||||
SPUtils.setString(Constants.SP_REGULATION_TEST_PASS_STATUS, "pass")
|
||||
}
|
||||
}
|
||||
@ -257,6 +261,21 @@ class DefaultJsApi(var context: Context) {
|
||||
runOnUiThread { DirectUtils.directToWebView(context, url.toString(), "内部网页") }
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun postWearBadgeTask(msg: Any) {
|
||||
EnergyTaskHelper.postEnergyTask("wear_badge")
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun startEnergyCenter(msg: Any) {
|
||||
context.startActivity(EnergyCenterActivity.getIntent(context))
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun startEnergyHouse(msg: Any) {
|
||||
context.startActivity(EnergyHouseActivity.getIntent(context))
|
||||
}
|
||||
|
||||
@Keep
|
||||
internal data class ImageEvent(var imageList: ArrayList<String> = arrayListOf(), var position: Int = 0)
|
||||
|
||||
|
||||
@ -344,6 +344,11 @@ object DefaultUrlHandler {
|
||||
return true
|
||||
}
|
||||
|
||||
// 处理内部页面逻辑
|
||||
if (transformNormalScheme(context, url, entrance)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if ("http" != uri.scheme && "https" != uri.scheme) return true
|
||||
return false
|
||||
}
|
||||
@ -360,7 +365,7 @@ object DefaultUrlHandler {
|
||||
uri.path?.apply {
|
||||
when {
|
||||
contains("game") -> {
|
||||
val gameId = uri.getQueryParameter("gameId") ?: ""
|
||||
val gameId = uri.getQueryParameter("gameId") ?: uri.pathSegments.last() ?: ""
|
||||
DirectUtils.directToGameDetail(context, gameId, entrance, autoDownload = false, traceEvent = null)
|
||||
}
|
||||
contains("question") -> {
|
||||
|
||||
@ -29,31 +29,31 @@ class TimeElapsedHelper(val fragment: Fragment?, val activity: Activity?) {
|
||||
|
||||
init {
|
||||
activity?.application?.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
|
||||
override fun onActivityStarted(a: Activity?) {
|
||||
override fun onActivityStarted(a: Activity) {
|
||||
}
|
||||
|
||||
override fun onActivitySaveInstanceState(a: Activity?, outState: Bundle?) {
|
||||
override fun onActivitySaveInstanceState(a: Activity, outState: Bundle) {
|
||||
}
|
||||
|
||||
override fun onActivityStopped(a: Activity?) {
|
||||
override fun onActivityStopped(a: Activity) {
|
||||
}
|
||||
|
||||
override fun onActivityCreated(a: Activity?, savedInstanceState: Bundle?) {
|
||||
override fun onActivityCreated(a: Activity, savedInstanceState: Bundle?) {
|
||||
}
|
||||
|
||||
override fun onActivityPaused(a: Activity?) {
|
||||
override fun onActivityPaused(a: Activity) {
|
||||
if (activity == a) {
|
||||
pauseCounting()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResumed(a: Activity?) {
|
||||
override fun onActivityResumed(a: Activity) {
|
||||
if (activity == a) {
|
||||
resumeCounting()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityDestroyed(a: Activity?) {
|
||||
override fun onActivityDestroyed(a: Activity) {
|
||||
if (activity == a) {
|
||||
HaloApp.getInstance().application.unregisterActivityLifecycleCallbacks(this)
|
||||
}
|
||||
|
||||
@ -131,6 +131,8 @@ public class Constants {
|
||||
public static final String SP_BRAND_NEW_USER = "brand_new_user";
|
||||
//包名检测是否点击不再提示
|
||||
public static final String SP_PACKAGE_CHECK = "package_check";
|
||||
//游戏详情预约引导提示
|
||||
public static final String SP_GAME_DETAIL_RESERVE_GUIDE = "game_detail_reserve_guide";
|
||||
|
||||
public static final String SP_XAPK_UNZIP_ACTIVITY = "xapk_unzip_activity";
|
||||
public static final String SP_XAPK_URL = "xapk_url";
|
||||
@ -177,6 +179,22 @@ public class Constants {
|
||||
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 String COMMODITY_DETAIL_ADDRESS_DEV = "https://static-web.ghzs.com/shop-dev/index.html#/product?from=ghzs";
|
||||
public static final String COMMODITY_DETAIL_ADDRESS = "https://static-web.ghzs.com/shop/index.html#/product?from=ghzs";
|
||||
|
||||
// 光能记录
|
||||
public static final String ENERGY_RECORD_ADDRESS_DEV = "https://static-web.ghzs.com/shop-dev/index.html#/record?from=ghzs";
|
||||
public static final String ENERGY_RECORD_ADDRESS = "https://static-web.ghzs.com/shop/index.html#/record?from=ghzs";
|
||||
|
||||
// 订单中心
|
||||
public static final String ORDER_CENTER_ADDRESS_DEV = "https://static-web.ghzs.com/shop-dev/index.html#/orders?from=ghzs";
|
||||
public static final String ORDER_CENTER_ADDRESS = "https://static-web.ghzs.com/shop/index.html#/orders?from=ghzs";
|
||||
|
||||
// 订单详情
|
||||
public static final String ORDER_DETAIL_ADDRESS_DEV = "https://static-web.ghzs.com/shop-dev/index.html#/order-detail?from=ghzs";
|
||||
public static final String ORDER_DETAIL_ADDRESS = "https://static-web.ghzs.com/shop/index.html#/order-detail?from=ghzs";
|
||||
|
||||
//最少需要多少数据才能上传
|
||||
public static final int DATA_AMOUNT = 20;
|
||||
|
||||
|
||||
@ -4,6 +4,8 @@ import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.gh.common.util.MtaHelper
|
||||
import com.lightgame.dialog.BaseDialogFragment
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
@ -63,4 +65,29 @@ abstract class BaseTrackableDialogFragment : BaseDialogFragment() {
|
||||
|
||||
open fun trackWithBasicDeviceInfo() = false
|
||||
|
||||
|
||||
override fun show(manager: FragmentManager, tag: String?) {
|
||||
val fragment = manager.findFragmentByTag(tag)
|
||||
if (fragment != null) {
|
||||
val transaction = manager.beginTransaction()
|
||||
transaction.show(fragment)
|
||||
transaction.commit()
|
||||
} else {
|
||||
try {
|
||||
val clazz: Class<*> = DialogFragment::class.java
|
||||
val dismissed = clazz.getDeclaredField("mDismissed")
|
||||
dismissed.isAccessible = true
|
||||
dismissed[this] = false
|
||||
val shownByMe = clazz.getDeclaredField("mShownByMe")
|
||||
shownByMe.isAccessible = true
|
||||
shownByMe[this] = true
|
||||
val transaction = manager.beginTransaction()
|
||||
transaction.add(this, tag)
|
||||
transaction.commitAllowingStateLoss()
|
||||
} catch (e: Exception) {
|
||||
super.show(manager, tag)
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,7 +215,7 @@ class DeviceRemindDialog(context: Context, val entity: DeviceDialogEntity, val g
|
||||
|
||||
class LooperHandle(val mAdapter: BannerAdapter) : Handler() {
|
||||
private val mWeakReference: WeakReference<BannerAdapter> = WeakReference(mAdapter)
|
||||
override fun handleMessage(msg: Message?) {
|
||||
override fun handleMessage(msg: Message) {
|
||||
val adapter = mWeakReference.get()
|
||||
adapter?.scrollToNextPage()
|
||||
adapter?.startScroll()
|
||||
|
||||
@ -67,7 +67,7 @@ class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
|
||||
activateTv.setOnClickListener {
|
||||
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击立即开启")
|
||||
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "${styleEntity.scenes}_${styleEntity.styleNo}_点击立即开启")
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
//这种方案适用于 API 26, 即8.0(含8.0)以上可以用
|
||||
val intent = Intent()
|
||||
@ -80,7 +80,7 @@ class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
|
||||
}
|
||||
|
||||
closeIv.setOnClickListener {
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击关闭")
|
||||
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "${styleEntity.scenes}_${styleEntity.styleNo}_点击关闭")
|
||||
}
|
||||
|
||||
@ -260,6 +260,8 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
|
||||
return
|
||||
}
|
||||
|
||||
if (activity.isFinishing) return
|
||||
|
||||
var dialogFragment = activity.supportFragmentManager.findFragmentByTag(PackageCheckDialogFragment::class.java.simpleName) as? PackageCheckDialogFragment
|
||||
if (dialogFragment == null) {
|
||||
dialogFragment = PackageCheckDialogFragment()
|
||||
@ -283,7 +285,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
|
||||
|
||||
val isPackagesInstall: (ArrayList<String>) -> Boolean = { packages ->
|
||||
var isPackagesInstalled = false
|
||||
packages.forEach {packageName->
|
||||
packages.forEach { packageName ->
|
||||
val isInstalled = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0).find { it.packageName == packageName } != null
|
||||
if (isInstalled) {
|
||||
isPackagesInstalled = true
|
||||
|
||||
@ -13,7 +13,9 @@ data class ExposureEntity(
|
||||
val gameName: String? = "",
|
||||
val gameVersion: String? = "",
|
||||
val sequence: Int? = 0,
|
||||
val outerSequence: Int? = 0,
|
||||
val platform: String? = "",
|
||||
var isMirrorData: Boolean = false,
|
||||
val downloadType: String? = "",
|
||||
val downloadCompleteType: String? = "",
|
||||
|
||||
|
||||
@ -36,10 +36,12 @@ data class ExposureEvent(
|
||||
return ExposureEvent(
|
||||
payload = ExposureEntity(
|
||||
gameId = gameEntity?.id?.getFirstElementDividedByDivider(Constants.GAME_ID_DIVIDER),
|
||||
gameName = gameEntity?.name?.removeSuffix(Constants.GAME_NAME_DECORATOR),
|
||||
gameVersion = gameEntity?.gameVersion,
|
||||
sequence = gameEntity?.sequence,
|
||||
platform = gameEntity?.platform,
|
||||
gameName = eTrace?.firstOrNull()?.payload?.gameName ?: gameEntity?.name?.removeSuffix(Constants.GAME_NAME_DECORATOR),
|
||||
gameVersion = eTrace?.firstOrNull()?.payload?.gameVersion ?:gameEntity?.gameVersion,
|
||||
isMirrorData = eTrace?.firstOrNull()?.payload?.isMirrorData ?: gameEntity?.shouldUseMirrorInfo() ?: false,
|
||||
sequence = eTrace?.firstOrNull()?.payload?.sequence ?: gameEntity?.sequence,
|
||||
outerSequence = eTrace?.firstOrNull()?.payload?.outerSequence ?: gameEntity?.outerSequence,
|
||||
platform = eTrace?.firstOrNull()?.payload?.platform ?:gameEntity?.platform,
|
||||
downloadType = gameEntity?.downloadType,
|
||||
downloadCompleteType = gameEntity?.downloadCompleteType,
|
||||
// ugly
|
||||
|
||||
@ -11,20 +11,16 @@ import io.reactivex.functions.Consumer
|
||||
*/
|
||||
class ExposureListener(var fragment: Fragment, var exposable: IExposable) : RecyclerView.OnScrollListener() {
|
||||
|
||||
var throttleBus: ExposureThrottleBus? = null
|
||||
val throttleBus: ExposureThrottleBus by lazy { ExposureThrottleBus(Consumer { commitExposure(it) }, Consumer(Throwable::printStackTrace)) }
|
||||
var layoutManager: LinearLayoutManager? = null
|
||||
var visibleState: ExposureThrottleBus.VisibleState? = null
|
||||
|
||||
init {
|
||||
fragment.fragmentManager?.registerFragmentLifecycleCallbacks(
|
||||
object : FragmentManager.FragmentLifecycleCallbacks() {
|
||||
override fun onFragmentResumed(fm: FragmentManager, f: Fragment) {
|
||||
throttleBus = ExposureThrottleBus(Consumer { commitExposure(it) }, Consumer(Throwable::printStackTrace))
|
||||
}
|
||||
|
||||
override fun onFragmentPaused(fm: FragmentManager, f: Fragment) {
|
||||
visibleState?.let { commitExposure(it) }
|
||||
throttleBus?.clear()
|
||||
throttleBus.clear()
|
||||
}
|
||||
|
||||
override fun onFragmentViewDestroyed(fm: FragmentManager, f: Fragment) {
|
||||
@ -44,7 +40,7 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
|
||||
layoutManager?.run {
|
||||
visibleState = ExposureThrottleBus.VisibleState(findFirstVisibleItemPosition(), findLastVisibleItemPosition())
|
||||
throttleBus?.postVisibleState(visibleState!!)
|
||||
throttleBus.postVisibleState(visibleState!!)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,8 +40,10 @@ object ExposureManager {
|
||||
loghubHelper.init(HaloApp.getInstance().application, ENDPOINT, PROJECT, LOG_STORE) { TimeUtil.currentTimeMillis() }
|
||||
|
||||
exposureExecutor.execute {
|
||||
val eventList = exposureDao.getAll()
|
||||
exposureSet.addAll(eventList)
|
||||
tryWithDefaultCatch {
|
||||
val eventList = exposureDao.getAll()
|
||||
exposureSet.addAll(eventList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +140,7 @@ object ExposureManager {
|
||||
return log
|
||||
}
|
||||
|
||||
internal class FixedSizeLinkedHashSet<T>(var maxSize: Int) : LinkedHashSet<T>() {
|
||||
class FixedSizeLinkedHashSet<T>(var maxSize: Int) : LinkedHashSet<T>() {
|
||||
override fun add(element: T): Boolean {
|
||||
if (size == maxSize) {
|
||||
pop()
|
||||
|
||||
@ -8,10 +8,11 @@ import com.gh.common.util.toObject
|
||||
import com.gh.gamecenter.entity.ApkEntity
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.halo.assistant.HaloApp
|
||||
import java.util.*
|
||||
|
||||
object ExposureUtils {
|
||||
|
||||
private val mDownloadCompleteTraceEventIdSet = ExposureManager.FixedSizeLinkedHashSet<String>(3)
|
||||
|
||||
@JvmStatic
|
||||
fun logADownloadExposureEvent(entity: GameEntity,
|
||||
platform: String?,
|
||||
@ -23,7 +24,8 @@ object ExposureUtils {
|
||||
} else {
|
||||
entity.id
|
||||
}
|
||||
gameEntity.gameVersion = entity.getApk().elementAtOrNull(0)?.version ?: gameEntity.gameVersion
|
||||
gameEntity.gameVersion = entity.getApk().elementAtOrNull(0)?.version
|
||||
?: gameEntity.gameVersion
|
||||
gameEntity.platform = platform
|
||||
gameEntity.downloadType = downloadType.toString()
|
||||
val exposureEvent = ExposureEvent.createEvent(gameEntity = gameEntity,
|
||||
@ -45,6 +47,14 @@ object ExposureUtils {
|
||||
gameEntity.platform = platform
|
||||
gameEntity.downloadCompleteType = downloadType.toString()
|
||||
val traceEvent = trace?.toObject<ExposureEvent>()
|
||||
|
||||
// 避免生成 trace 相同的下载完成事件,根据日志看下载完成的同一秒有可能生成两条
|
||||
if (mDownloadCompleteTraceEventIdSet.contains(traceEvent?.id)) {
|
||||
return
|
||||
}
|
||||
|
||||
traceEvent?.payload?.gameId?.let { mDownloadCompleteTraceEventIdSet.add(it) }
|
||||
|
||||
val exposureEvent = ExposureEvent.createEvent(gameEntity = gameEntity,
|
||||
source = traceEvent?.source ?: ArrayList(),
|
||||
eTrace = ExposureTraceUtils.appendTrace(traceEvent),
|
||||
@ -80,6 +90,15 @@ object ExposureUtils {
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun updateExposureSequence(gameList: List<GameEntity>?) {
|
||||
gameList?.let {
|
||||
for ((index, game) in it.withIndex()) {
|
||||
game.sequence = index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class DownloadType {
|
||||
DOWNLOAD,
|
||||
|
||||
|
||||
@ -8,10 +8,10 @@ import kotlinx.android.parcel.Parcelize
|
||||
@Parcelize
|
||||
data class Meta(
|
||||
val mac: String? = "",
|
||||
val imei: String? = "",
|
||||
val jnfj: String? = "",
|
||||
val model: String? = "",
|
||||
val manufacturer: String? = "",
|
||||
val android_id: String? = "",
|
||||
val dia: String? = "",
|
||||
val android_sdk: Int? = -1,
|
||||
val android_version: String? = "",
|
||||
val network: String? = "",
|
||||
|
||||
@ -11,6 +11,7 @@ import android.telephony.TelephonyManager
|
||||
import android.text.TextUtils
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.SPUtils
|
||||
import com.gh.common.util.tryWithDefaultCatch
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.halo.assistant.HaloApp
|
||||
@ -26,13 +27,25 @@ object MetaUtil {
|
||||
private var imei: String? = null
|
||||
private var base64EncodedImei: String? = null
|
||||
private var androidId: String? = null
|
||||
private var base64EncodedAndroidId: String? = null
|
||||
|
||||
private var romName: String? = null
|
||||
private var romVersion: String? = null
|
||||
|
||||
fun refreshMeta() {
|
||||
|
||||
if (romName == null) {
|
||||
tryWithDefaultCatch {
|
||||
romName = RomIdentifier.getRom().name
|
||||
romVersion = RomIdentifier.getRom().versionName
|
||||
}
|
||||
}
|
||||
|
||||
m = Meta(mac = "",
|
||||
imei = getIMEI(),
|
||||
jnfj = getBase64EncodedIMEI(),
|
||||
model = getModel(),
|
||||
manufacturer = getManufacturer(),
|
||||
android_id = getAndroidId(),
|
||||
dia = getBase64EncodedAndroidId(),
|
||||
android_sdk = getAndroidSDK(),
|
||||
android_version = getAndroidVersion(),
|
||||
network = getNetwork(),
|
||||
@ -43,7 +56,7 @@ object MetaUtil {
|
||||
appVersion = BuildConfig.VERSION_NAME,
|
||||
userId = UserManager.getInstance().userId,
|
||||
exposureVersion = BuildConfig.EXPOSURE_VERSION,
|
||||
rom = RomIdentifier.getRom().name + "" + RomIdentifier.getRom().versionName)
|
||||
rom = romName + "" + romVersion)
|
||||
}
|
||||
|
||||
fun getMeta(): Meta {
|
||||
@ -107,6 +120,10 @@ object MetaUtil {
|
||||
|
||||
@JvmStatic
|
||||
fun getBase64EncodedIMEI(): String {
|
||||
if (imei == null) {
|
||||
getIMEI()
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(base64EncodedImei) && imei != null) {
|
||||
try {
|
||||
base64EncodedImei = android.util.Base64.encodeToString(getIMEI().trim().toByteArray(), android.util.Base64.NO_WRAP)
|
||||
@ -119,6 +136,24 @@ object MetaUtil {
|
||||
return base64EncodedImei ?: ""
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getBase64EncodedAndroidId(): String {
|
||||
if (androidId == null) {
|
||||
getAndroidId()
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(base64EncodedAndroidId) && androidId != null) {
|
||||
try {
|
||||
base64EncodedAndroidId = android.util.Base64.encodeToString(getAndroidId().trim().toByteArray(), android.util.Base64.NO_WRAP)
|
||||
} catch (e: java.lang.Exception) {
|
||||
e.printStackTrace()
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
return base64EncodedAndroidId ?: ""
|
||||
}
|
||||
|
||||
fun getModel(): String? {
|
||||
return Build.MODEL
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ object RegionSettingHelper {
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
SPUtils.getString(SP_SETTING).toObject<RegionSetting>()?.let {
|
||||
SPUtils.getString(SP_SETTING)?.toObject<RegionSetting>()?.let {
|
||||
updateSettingsInMemory(it)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 = 7, exportSchema = false)
|
||||
@Database(entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class], version = 8, exportSchema = false)
|
||||
@TypeConverters(CountConverter::class,
|
||||
CommunityConverter::class,
|
||||
TimeConverter::class,
|
||||
@ -23,8 +23,10 @@ import com.halo.assistant.HaloApp
|
||||
ThumbnailConverter::class,
|
||||
TagStyleListConverter::class,
|
||||
StringArrayListConverter::class,
|
||||
ListStringConverter::class,
|
||||
CommunityVideoConverter::class,
|
||||
UserConverter::class)
|
||||
UserConverter::class,
|
||||
ImageInfoConverter::class)
|
||||
|
||||
abstract class HistoryDatabase : RoomDatabase() {
|
||||
|
||||
@ -69,6 +71,14 @@ abstract class HistoryDatabase : RoomDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
val MIGRATION_7_8: Migration = object : Migration(7, 8) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("Alter TABLE ArticleEntity add images TEXT NOT NULL DEFAULT ''")
|
||||
database.execSQL("Alter TABLE ArticleEntity add imagesInfo TEXT NOT NULL DEFAULT ''")
|
||||
database.execSQL("Alter TABLE AnswerEntity add imagesInfo TEXT NOT NULL DEFAULT ''")
|
||||
}
|
||||
}
|
||||
|
||||
val instance by lazy {
|
||||
Room.databaseBuilder(HaloApp.getInstance().application, HistoryDatabase::class.java, "USER_TRACK_HISTORY_DATABASE")
|
||||
.addMigrations(MIGRATION_2_3)
|
||||
@ -76,6 +86,7 @@ abstract class HistoryDatabase : RoomDatabase() {
|
||||
.addMigrations(MIGRATION_4_5)
|
||||
.addMigrations(MIGRATION_5_6)
|
||||
.addMigrations(MIGRATION_6_7)
|
||||
.addMigrations(MIGRATION_7_8)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,48 +69,44 @@ object HistoryHelper {
|
||||
@JvmStatic
|
||||
fun insertNewsEntity(newsEntity: NewsEntity) {
|
||||
newsEntity.orderTag = System.currentTimeMillis()
|
||||
runOnIoThread { HistoryDatabase.instance.newsDao().addNews(newsEntity) }
|
||||
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.newsDao().addNews(newsEntity) } }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteNewsEntity(newsId: String) {
|
||||
runOnIoThread { HistoryDatabase.instance.newsDao().deleteNews(NewsEntity().apply { id = newsId }) }
|
||||
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.newsDao().deleteNews(NewsEntity().apply { id = newsId }) } }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteGameEntity(gameId: String) {
|
||||
runOnIoThread { HistoryDatabase.instance.gameDao().deleteGame(HistoryGameEntity(id = gameId)) }
|
||||
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.gameDao().deleteGame(HistoryGameEntity(id = gameId)) } }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteArticleEntity(articleId: String) {
|
||||
runOnIoThread { HistoryDatabase.instance.articleDao().deleteArticle(ArticleEntity(id = articleId)) }
|
||||
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.articleDao().deleteArticle(ArticleEntity(id = articleId)) } }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteAnswerEntity(answerId: String) {
|
||||
runOnIoThread { HistoryDatabase.instance.answerDao().deleteAnswer(AnswerEntity().apply { primaryKey = answerId }) }
|
||||
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.answerDao().deleteAnswer(AnswerEntity().apply { primaryKey = answerId }) } }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteVideoEntity(videoId: String) {
|
||||
runOnIoThread { HistoryDatabase.instance.videoHistoryDao().deleteVideo(MyVideoEntity().apply { id = videoId }) }
|
||||
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.videoHistoryDao().deleteVideo(MyVideoEntity().apply { id = videoId }) } }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun emptyDatabase() {
|
||||
runOnIoThread { HistoryDatabase.instance.clearAllTables() }
|
||||
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.clearAllTables() } }
|
||||
}
|
||||
|
||||
private fun convertArticleDetailToArticle(articleDetailEntity: ArticleDetailEntity): ArticleEntity {
|
||||
val articleEntity = ArticleEntity()
|
||||
|
||||
articleEntity.id = articleDetailEntity.id
|
||||
articleEntity.brief = articleDetailEntity.content.
|
||||
removeVideoContent().
|
||||
removeInsertedContent().
|
||||
clearHtmlFormatCompletely().
|
||||
replace(" +".toRegex()," ")
|
||||
articleEntity.brief = articleDetailEntity.content.removeVideoContent().removeInsertedContent().clearHtmlFormatCompletely().replace(" +".toRegex(), " ")
|
||||
articleEntity.count = articleDetailEntity.count
|
||||
articleDetailEntity.community.id = articleDetailEntity.communityId
|
||||
articleEntity.community = articleDetailEntity.community
|
||||
@ -118,6 +114,9 @@ object HistoryHelper {
|
||||
articleEntity.title = articleDetailEntity.title
|
||||
articleEntity.user = articleDetailEntity.user
|
||||
articleEntity.orderTag = System.currentTimeMillis()
|
||||
articleEntity.images = articleDetailEntity.images
|
||||
articleEntity.imagesInfo = articleDetailEntity.imagesInfo
|
||||
articleEntity.videos = articleDetailEntity.videos
|
||||
|
||||
return articleEntity
|
||||
}
|
||||
@ -132,12 +131,11 @@ object HistoryHelper {
|
||||
answerEntity.vote = answerDetailEntity.vote
|
||||
answerEntity.user = answerDetailEntity.user
|
||||
answerEntity.orderTag = System.currentTimeMillis()
|
||||
answerEntity.brief = answerDetailEntity.content.
|
||||
removeVideoContent().
|
||||
removeInsertedContent().
|
||||
clearHtmlFormatCompletely().
|
||||
replace(" +".toRegex(), " ")
|
||||
answerEntity.brief = answerDetailEntity.content.removeVideoContent().removeInsertedContent().clearHtmlFormatCompletely().replace(" +".toRegex(), " ")
|
||||
answerEntity.time = answerDetailEntity.time
|
||||
answerEntity.images = answerDetailEntity.images
|
||||
answerEntity.imagesInfo = answerDetailEntity.imagesInfo
|
||||
answerEntity.videos = answerDetailEntity.videos
|
||||
|
||||
return answerEntity
|
||||
}
|
||||
|
||||
@ -25,8 +25,10 @@ object LoghubUtils {
|
||||
mApplication = application
|
||||
|
||||
loghubEventExecutor.execute {
|
||||
val eventList = loghubEventDao.getAll()
|
||||
loghubEventSet.addAll(eventList)
|
||||
tryWithDefaultCatch {
|
||||
val eventList = loghubEventDao.getAll()
|
||||
loghubEventSet.addAll(eventList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -20,7 +20,12 @@ class VolumeObserver(var context: Context, handler: Handler, var callback: MuteC
|
||||
super.onChange(selfChange)
|
||||
|
||||
val audio = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
val currentVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
var currentVolume = 0
|
||||
|
||||
tryCatchInRelease {
|
||||
// 部分设备(Meizu 7.1.2 M6 Note)的 audioManager getStreamVolume 内部会触发空指针 :(
|
||||
currentVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
}
|
||||
|
||||
val delta = previousVolume - currentVolume
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ import android.view.View
|
||||
import android.view.Window
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.g00fy2.versioncompare.Version
|
||||
@ -23,6 +24,7 @@ import com.gh.gamecenter.entity.TrackableEntity
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.*
|
||||
import com.lightgame.utils.Utils
|
||||
import java.lang.ref.WeakReference
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class SimulatorDownloadManager private constructor() {
|
||||
@ -34,6 +36,7 @@ class SimulatorDownloadManager private constructor() {
|
||||
private var appProgressFilling: View? = null
|
||||
private var appProgressAnchor: View? = null
|
||||
private var downloadDialog: Dialog? = null
|
||||
private var mContextRef: WeakReference<Context>? = null
|
||||
|
||||
private var simulatorLocation: SimulatorLocation? = null
|
||||
private var simulator: SimulatorEntity? = null
|
||||
@ -71,7 +74,10 @@ class SimulatorDownloadManager private constructor() {
|
||||
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()
|
||||
val activity = mContextRef?.get() as? AppCompatActivity
|
||||
if (activity?.isFinishing == false) {
|
||||
downloadDialog?.dismiss()
|
||||
}
|
||||
}
|
||||
DownloadStatus.neterror == downloadEntity.status -> {
|
||||
ToastUtils.showToast("网络不稳定,下载任务已暂停")
|
||||
@ -94,7 +100,9 @@ class SimulatorDownloadManager private constructor() {
|
||||
showDownloadDialog(context, simulator, location, "", "", null)
|
||||
}
|
||||
|
||||
fun showDownloadDialog(context: Context, simulator: SimulatorEntity?, location: SimulatorLocation, gameId: String = "", gameName: String = "", cancelCallback: (() -> Unit)? = null) {
|
||||
fun showDownloadDialog(context: Context?, simulator: SimulatorEntity?, location: SimulatorLocation, gameId: String = "", gameName: String = "", cancelCallback: (() -> Unit)? = null) {
|
||||
if (context == null) return
|
||||
mContextRef = WeakReference(context)
|
||||
this.simulatorLocation = location
|
||||
this.simulator = simulator
|
||||
this.gameId = gameId
|
||||
@ -153,7 +161,10 @@ class SimulatorDownloadManager private constructor() {
|
||||
view.findViewById<View>(R.id.app_tv_cancel).setOnClickListener {
|
||||
DownloadManager.getInstance(context).pause(simulator?.apk?.url)
|
||||
MtaHelper.onEvent("模拟器下载", "下载中弹窗", "点击关闭")
|
||||
downloadDialog?.dismiss()
|
||||
val activity = mContextRef?.get() as? AppCompatActivity
|
||||
if (activity?.isFinishing == false) {
|
||||
downloadDialog?.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
downloadDialog?.setOnDismissListener {
|
||||
|
||||
@ -33,7 +33,7 @@ object SimulatorGameManager {
|
||||
|
||||
@JvmStatic
|
||||
fun deleteLocalGames(names: List<String>) {
|
||||
val downloadEntityList = DownloadDao.getInstance(HaloApp.getInstance().application).all
|
||||
val downloadEntityList = DownloadManager.getInstance(HaloApp.getInstance().application).allDownloadEntity
|
||||
names.forEach { name ->
|
||||
val downloadEntity = downloadEntityList.find { it.name == name }
|
||||
if (downloadEntity != null) {
|
||||
@ -48,7 +48,7 @@ object SimulatorGameManager {
|
||||
|
||||
@JvmStatic
|
||||
fun deleteLocalGame(name: String) {
|
||||
val downloadEntityList = DownloadDao.getInstance(HaloApp.getInstance().application).all
|
||||
val downloadEntityList = DownloadManager.getInstance(HaloApp.getInstance().application).allDownloadEntity
|
||||
val downloadEntity = downloadEntityList.find { it.name == name }
|
||||
if (downloadEntity != null) {
|
||||
val file = File(downloadEntity.path)
|
||||
@ -109,7 +109,7 @@ object SimulatorGameManager {
|
||||
val destActivity = "com.gh.emu.RequestPermissionActivity"
|
||||
intent.setClassName(gameEntity.simulator?.apk?.packageName ?: "", destActivity)
|
||||
try {
|
||||
AppManager.getInstance().recentActiveActivity.startActivity(intent)
|
||||
AppManager.getInstance().recentActiveActivity?.startActivity(intent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
ToastUtils.showToast("模拟器安装错误")
|
||||
}
|
||||
|
||||
@ -52,8 +52,8 @@ public class DataLogUtils {
|
||||
String user = Installation.getUUID(context);
|
||||
String channel = HaloApp.getInstance().getChannel();
|
||||
map.put("version", version);
|
||||
map.put("user", user);
|
||||
map.put("device_id", MetaUtil.getIMEI());
|
||||
map.put("resu", user);
|
||||
map.put("jnfj", MetaUtil.getBase64EncodedIMEI());
|
||||
map.put("channel", channel);
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
|
||||
@ -42,6 +42,15 @@ public class DataUtils {
|
||||
}
|
||||
|
||||
SentryAndroid.init(context, options -> {
|
||||
// Sentry 疯狂报 ANR (很大一部分还是莫名奇妙的 ANR)严重影响到其它闪退日志的收集
|
||||
// 这里将它局限到只有官网渠道的包才统计 ANR
|
||||
if ("GH_206".equals(channel)) {
|
||||
options.setAnrEnabled(true);
|
||||
options.setAnrTimeoutIntervalMillis(6000);
|
||||
} else {
|
||||
options.setAnrEnabled(false);
|
||||
}
|
||||
|
||||
options.setDebug(BuildConfig.DEBUG);
|
||||
options.setEnableSessionTracking(true);
|
||||
options.setEnvironment(BuildConfig.FLAVOR);
|
||||
@ -57,12 +66,8 @@ public class DataUtils {
|
||||
});
|
||||
|
||||
Sentry.configureScope(scope -> {
|
||||
User user = new User();
|
||||
user.setId(HaloApp.getInstance().getGid());
|
||||
scope.setUser(user);
|
||||
|
||||
if (BuildConfig.BUILD_TIME != 0L) {
|
||||
scope.setTag("alias", "内测版" + BuildConfig.VERSION_NAME + "_" + BuildConfig.BUILD_TIME);
|
||||
scope.setTag("alias", "内测版" + BuildConfig.VERSION_NAME);
|
||||
} else {
|
||||
scope.setTag("alias", "正式版" + BuildConfig.VERSION_NAME);
|
||||
scope.setTag("channel", channel);
|
||||
@ -229,7 +234,7 @@ public class DataUtils {
|
||||
|
||||
kv.put("版本", platform);
|
||||
kv.put("用户机型", Build.MODEL);
|
||||
kv.put("设备IMEI", MetaUtil.getIMEI());
|
||||
kv.put("设备JNFJ", MetaUtil.getBase64EncodedIMEI());
|
||||
kv.put("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
|
||||
kv.put("光环助手版本", BuildConfig.VERSION_NAME);
|
||||
kv.put("位置", entrance);
|
||||
|
||||
@ -41,11 +41,11 @@ public class DeviceUtils {
|
||||
context = context.getApplicationContext();
|
||||
JSONObject object = new JSONObject();
|
||||
object.put("os", "Android");
|
||||
object.put("imei", MetaUtil.getIMEI());
|
||||
object.put("jnfj", MetaUtil.getBase64EncodedIMEI());
|
||||
object.put("mac", getMac(context));
|
||||
object.put("model", MODEL);
|
||||
object.put("manufacturer", MANUFACTURER);
|
||||
object.put("android_id", MetaUtil.getAndroidId());
|
||||
object.put("dia", MetaUtil.getBase64EncodedAndroidId());
|
||||
object.put("android_sdk", Build.VERSION.SDK_INT);
|
||||
object.put("android_version", android.os.Build.VERSION.RELEASE);
|
||||
object.put("ip", "");
|
||||
@ -57,8 +57,8 @@ public class DeviceUtils {
|
||||
public static JSONObject getUserDevice(Context context) { // 判断新老用户device数据
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put("IMEI", MetaUtil.getIMEI());
|
||||
object.put("ANDROID_ID", MetaUtil.getAndroidId());
|
||||
object.put("JNFJ", MetaUtil.getBase64EncodedIMEI());
|
||||
object.put("DIA", MetaUtil.getBase64EncodedAndroidId());
|
||||
object.put("MAC", getMac(context));
|
||||
// object.put("MTA_ID", StatConfig.getMid(context));
|
||||
object.put("MANUFACTURER", MANUFACTURER);
|
||||
|
||||
@ -1902,6 +1902,95 @@ public class DialogUtils {
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static Dialog showCancelOrDeleteReservationDialog(Context context, String title, String message
|
||||
, String positive, String negative, final ConfirmListener cmListener, final CancelListener clListener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_cancel_reservation, 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);
|
||||
TextView positiveTv = contentView.findViewById(R.id.dialog_positive);
|
||||
contentTv.setText(message);
|
||||
titleTv.setText(title);
|
||||
negativeTv.setText(negative);
|
||||
positiveTv.setText(positive);
|
||||
|
||||
negativeTv.setOnClickListener(view -> {
|
||||
if (clListener != null) {
|
||||
clListener.onCancel();
|
||||
}
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
positiveTv.setOnClickListener(view -> {
|
||||
if (cmListener != null) {
|
||||
cmListener.onConfirm();
|
||||
}
|
||||
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);
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static void showEnergyDialog(Context context, String userName, int energy) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_energy, null);
|
||||
((TextView)contentView.findViewById(R.id.userName)).setText("\"" + userName + "\"");
|
||||
((TextView)contentView.findViewById(R.id.energy)).setText(energy + "");
|
||||
|
||||
contentView.findViewById(R.id.dialog_positive).setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showEnergyTaskNoticeDialog(Context context, String title, String content) {
|
||||
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);
|
||||
TextView okTv = contentView.findViewById(R.id.dialog_ok);
|
||||
|
||||
if (title == null) {
|
||||
titleTv.setVisibility(View.GONE);
|
||||
} else {
|
||||
titleTv.setVisibility(View.VISIBLE);
|
||||
titleTv.setText(title);
|
||||
}
|
||||
contentTv.setText(content);
|
||||
|
||||
okTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
|
||||
okTv.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
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
@ -39,6 +40,8 @@ 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
|
||||
import com.gh.gamecenter.personalhome.background.PersonalityBackgroundActivity
|
||||
import com.gh.gamecenter.personalhome.border.AvatarBorderActivity
|
||||
import com.gh.gamecenter.qa.CommunityFragment
|
||||
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
|
||||
import com.gh.gamecenter.qa.article.SimpleArticleListActivity
|
||||
@ -48,10 +51,12 @@ 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.security.BindPhoneActivity
|
||||
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.user.UserViewModel
|
||||
import com.gh.gamecenter.video.data.VideoDataActivity
|
||||
import com.gh.gamecenter.video.detail.VideoDetailActivity
|
||||
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
|
||||
@ -249,6 +254,68 @@ object DirectUtils {
|
||||
|
||||
"bbs_detail" -> directForumDetail(context, linkEntity.link ?: "", entrance)
|
||||
|
||||
"mobile_bind" -> {
|
||||
CheckLoginUtils.checkLogin(context, entrance) {
|
||||
context.startActivity(BindPhoneActivity.getNormalIntent(context, false))
|
||||
}
|
||||
}
|
||||
|
||||
"authentication" -> {
|
||||
CheckLoginUtils.checkLogin(context, entrance) {
|
||||
context.startActivity(UserInfoEditActivity.getIntent(context, UserViewModel.TYPE_ID_CARD))
|
||||
}
|
||||
}
|
||||
|
||||
"user_background" -> {
|
||||
CheckLoginUtils.checkLogin(context, entrance) {
|
||||
context.startActivity(PersonalityBackgroundActivity.getIntent(context))
|
||||
}
|
||||
}
|
||||
|
||||
"avatar_frame" -> {
|
||||
CheckLoginUtils.checkLogin(context, entrance) {
|
||||
context.startActivity(AvatarBorderActivity.getIntent(context))
|
||||
}
|
||||
}
|
||||
|
||||
"badge" -> {
|
||||
CheckLoginUtils.checkLogin(context, entrance) {
|
||||
UserManager.getInstance().userInfoEntity?.run {
|
||||
directToBadgeWall(context, userId, name, icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"etiquette_exam" -> directToRegulationTestPage(context)
|
||||
|
||||
"setting" -> context.startActivity(SettingActivity.getIntent(context, false, entrance))
|
||||
|
||||
"index_page" -> directToHomeTab(context)
|
||||
|
||||
"video_upload" -> context.startActivity(VideoManagerActivity.getIntent(context, "", entrance))
|
||||
|
||||
"bbs" -> directToForum(context)
|
||||
|
||||
"user_page" -> directToHomeActivity(context, UserManager.getInstance().userId, "", entrance)
|
||||
|
||||
"video_tab" -> directToVideoTab(context)
|
||||
|
||||
"toolkit" -> context.startActivity(ToolBoxActivity.getIntent(context, entrance))
|
||||
|
||||
"toolkit_detail" -> {
|
||||
linkEntity.toolkit?.run {
|
||||
if (url != null && url!!.contains(Config.URL_ARTICLE)) {
|
||||
val newsId = url!!.substring(url!!.lastIndexOf("/") + 1, url!!.length - 5) // 5: ".html"
|
||||
val intent = NewsDetailActivity.getIntentById(context, newsId, entrance)
|
||||
context.startActivity(intent)
|
||||
} else {
|
||||
context.startActivity(WebActivity.getWebByCollectionTools(context, this, false))
|
||||
}
|
||||
} ?: ""
|
||||
}
|
||||
|
||||
"halo_tab" -> directToPersonalTab(context)
|
||||
|
||||
//"h5_game_center" -> directLetoGameCenter(context)
|
||||
|
||||
"" -> {
|
||||
@ -578,12 +645,17 @@ object DirectUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun directToExternalBrowser(context: Context, url: String) {
|
||||
if (url.isEmpty()) return
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(Uri.decode(url)))
|
||||
if (context !is AppCompatActivity) {
|
||||
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
try {
|
||||
if (url.isEmpty()) return
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(Uri.decode(url)))
|
||||
if (context !is AppCompatActivity) {
|
||||
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
context.startActivity(browserIntent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
e.printStackTrace()
|
||||
Utils.toast(context, "跳转地址无效")
|
||||
}
|
||||
context.startActivity(browserIntent)
|
||||
}
|
||||
|
||||
// 跳转 QQ,qqNumber 为空选择默认客服 QQ
|
||||
@ -1030,7 +1102,28 @@ object DirectUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 到首页论坛 tab
|
||||
* 到首页-首页 tab
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToHomeTab(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_HOME))
|
||||
}
|
||||
} else {
|
||||
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_HOME) })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 到首页-论坛 tab
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToForum(context: Context) {
|
||||
@ -1049,6 +1142,46 @@ object DirectUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 到首页-视频 tab
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToVideoTab(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_VIDEO))
|
||||
}
|
||||
} else {
|
||||
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_VIDEO) })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 到首页-我的光环 tab
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToPersonalTab(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_PERSONAL))
|
||||
}
|
||||
} else {
|
||||
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_PERSONAL) })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至使用帮助与反馈
|
||||
* @param position 使用帮助:[HelpAndFeedbackActivity.HELP_ITEM],意见反馈:[HelpAndFeedbackActivity.SUGGESTION_ITEM]
|
||||
@ -1060,4 +1193,67 @@ object DirectUtils {
|
||||
bundle.putInt(BaseActivity_TabLayout.PAGE_INDEX, position)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至商品详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToCommodityDetail(context: Context, commodityId: String) {
|
||||
var url: String = if ("internal" == BuildConfig.FLAVOR) {
|
||||
Constants.COMMODITY_DETAIL_ADDRESS_DEV
|
||||
} else {
|
||||
Constants.COMMODITY_DETAIL_ADDRESS
|
||||
}
|
||||
|
||||
url = String.format(Locale.CHINA, "%s&shopid=%s×tamp=%d", url, commodityId, (Date().time / 1000 / 1000.toFloat()).roundToInt())
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至光能记录(默认跳到光能记录第一个Tab)
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToEnergyRecord(context: Context) {
|
||||
directToEnergyRecord(context, 0)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToEnergyRecord(context: Context, position: Int) {
|
||||
var url: String = if ("internal" == BuildConfig.FLAVOR) {
|
||||
Constants.ENERGY_RECORD_ADDRESS_DEV
|
||||
} else {
|
||||
Constants.ENERGY_RECORD_ADDRESS
|
||||
}
|
||||
|
||||
url = String.format(Locale.CHINA, "%s&position=%s×tamp=%d", url, position, (Date().time / 1000 / 1000.toFloat()).roundToInt())
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至订单中心
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToOrderCenter(context: Context) {
|
||||
var url: String = if ("internal" == BuildConfig.FLAVOR) {
|
||||
Constants.ORDER_CENTER_ADDRESS_DEV
|
||||
} else {
|
||||
Constants.ORDER_CENTER_ADDRESS
|
||||
}
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至订单详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToOrderDetail(context: Context, orderId: String) {
|
||||
var url: String = if ("internal" == BuildConfig.FLAVOR) {
|
||||
Constants.ORDER_DETAIL_ADDRESS_DEV
|
||||
} else {
|
||||
Constants.ORDER_DETAIL_ADDRESS
|
||||
}
|
||||
|
||||
url = String.format(Locale.CHINA, "%s&order_id=%s×tamp=%d", url, orderId, (Date().time / 1000 / 1000.toFloat()).roundToInt())
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
}
|
||||
@ -125,16 +125,17 @@ public class DownloadItemUtils {
|
||||
public static void updateItemWithReserveStatus(GameViewHolder holder, GameEntity gameEntity) {
|
||||
if ("download".equals(gameEntity.getReserveStatus())) {
|
||||
// 已上线
|
||||
holder.gameDownloadBtn.setVisibility(View.VISIBLE);
|
||||
holder.gameDownloadBtn.setText("已上线");
|
||||
holder.gameDownloadBtn.setTextColor(Color.WHITE);
|
||||
holder.gameDownloadBtn.setBackground(ContextCompat.getDrawable(holder.gameDes.getContext(), R.drawable.game_item_btn_pause_dn));
|
||||
// holder.gameDownloadBtn.setVisibility(View.VISIBLE);
|
||||
// holder.gameDownloadBtn.setText("已上线");
|
||||
// holder.gameDownloadBtn.setTextColor(Color.WHITE);
|
||||
// holder.gameDownloadBtn.setBackground(ContextCompat.getDrawable(holder.gameDes.getContext(), R.drawable.game_item_btn_pause_dn));
|
||||
updateItem(holder.gameDes.getContext(), gameEntity, holder, false);
|
||||
} else if ("appointment".equals(gameEntity.getReserveStatus())) {
|
||||
// 已预约
|
||||
holder.gameDownloadBtn.setVisibility(View.VISIBLE);
|
||||
holder.gameDownloadBtn.setText("已预约");
|
||||
holder.gameDownloadBtn.setTextColor(Color.WHITE);
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_pause_dn);
|
||||
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(holder.gameDes.getContext(), R.color.aaaaaa));
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.button_round_f5f5f5);
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,7 +580,9 @@ public class DownloadItemUtils {
|
||||
final String location,
|
||||
@Nullable final ExposureEvent traceEvent) {
|
||||
String str = downloadBtn.getText().toString();
|
||||
ApkEntity apk = gameEntity.getApk().get(0);
|
||||
if (gameEntity.getApk().isEmpty()) return;
|
||||
ApkEntity apk = ExtensionsKt.safelyGetInRelease(gameEntity.getApk(), 0);
|
||||
if (apk == null) return;
|
||||
|
||||
if (str.equals(context.getString(R.string.download))) {
|
||||
// 先弹下载弹窗(如果需要的话)
|
||||
@ -654,6 +657,8 @@ public class DownloadItemUtils {
|
||||
}
|
||||
DataUtils.onGameLaunchEvent(context, gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), location);
|
||||
PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk().get(0).getPackageName());
|
||||
|
||||
EnergyTaskHelper.postEnergyTask("play_game", gameEntity.getId(), gameEntity.getApk().get(0).getPackageName());
|
||||
} else if (str.equals(context.getString(R.string.update))) {
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "更新", gameEntity.getName());
|
||||
@ -687,6 +692,8 @@ public class DownloadItemUtils {
|
||||
downloadBtn.setBackgroundResource(R.drawable.game_item_btn_downloading_style);
|
||||
downloadBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.text_downloading_style));
|
||||
DeviceRemindDialog.Companion.showDeviceRemindDialog(context, gameEntity);
|
||||
|
||||
EnergyTaskHelper.postEnergyTask("download_game", gameEntity.getId(), gameEntity.getApk().get(0).getPackageName());
|
||||
} else {
|
||||
Utils.toast(context, msg);
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ object DownloadObserver {
|
||||
}
|
||||
if (!downloadEntity.isPluggable) {
|
||||
if (downloadEntity.isSimulatorGame()) {
|
||||
val gameEntity = HaloApp.get(GameEntity::class.java.simpleName, true) as? GameEntity
|
||||
val gameEntity = HaloApp.get(downloadEntity.path, true) as? GameEntity
|
||||
if (gameEntity?.simulator != null) {
|
||||
val isInstalled = PackageUtils.isInstalledFromAllPackage(HaloApp.getInstance().application, gameEntity.simulator!!.apk!!.packageName)
|
||||
if (!isInstalled) {
|
||||
@ -219,7 +219,7 @@ object DownloadObserver {
|
||||
kv1["版本"] = platform
|
||||
kv1["状态"] = "下载完成"
|
||||
kv1["用户机型"] = Build.MODEL
|
||||
kv1["设备IMEI"] = MetaUtil.getIMEI()
|
||||
kv1["设备JNFJ"] = MetaUtil.getBase64EncodedIMEI()
|
||||
kv1["网络状态"] = DeviceUtils.getNetwork(HaloApp.getInstance().application)
|
||||
kv1["光环助手版本"] = BuildConfig.VERSION_NAME
|
||||
if (downloadEntity.isUpdate) {
|
||||
@ -287,7 +287,7 @@ object DownloadObserver {
|
||||
params["game"] = id
|
||||
params["platform"] = platform ?: ""
|
||||
val body = RequestBody.create(MediaType.parse("application/json"),
|
||||
JSONObject(params).toString())
|
||||
JSONObject(params as Map<*, *>).toString())
|
||||
RetrofitManager.getInstance(mApplication).api.postDownload(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
||||
121
app/src/main/java/com/gh/common/util/EnergyTaskHelper.kt
Normal file
121
app/src/main/java/com/gh/common/util/EnergyTaskHelper.kt
Normal file
@ -0,0 +1,121 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.PopupWindow
|
||||
import android.widget.TextView
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.EnergyTaskCompleteEntity
|
||||
import com.gh.gamecenter.energy.EnergyCenterActivity
|
||||
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.AppManager
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import org.json.JSONObject
|
||||
|
||||
/**
|
||||
* 上报光能任务辅助类
|
||||
*/
|
||||
object EnergyTaskHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun postEnergyTask(action: String) {
|
||||
postEnergyTask(action, null, null, null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun postEnergyTask(action: String, id: String) {
|
||||
postEnergyTask(action, id, null, null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun postEnergyTask(action: String, id: String, packageName: String) {
|
||||
postEnergyTask(action, id, packageName, null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun postEnergyTaskForWeb(action: String, url: String) {
|
||||
postEnergyTask(action, null, null, url)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun postEnergyTaskForShare(type: String, id: String, url: String) {
|
||||
when (type) {
|
||||
"游戏详情" -> postEnergyTask("share_game_detail", id)
|
||||
|
||||
"视频" -> postEnergyTask("share_video", id)
|
||||
|
||||
"资讯文章" -> postEnergyTask("share_article", id)
|
||||
|
||||
"问题详情" -> postEnergyTask("share_question", id)
|
||||
|
||||
"回答详情" -> postEnergyTask("share_answer", id)
|
||||
|
||||
"文章详情" -> postEnergyTask("share_community_article", id)
|
||||
|
||||
"工具箱" -> postEnergyTask("share_toolkit", id)
|
||||
|
||||
"web链接" -> postEnergyTaskForWeb("share_web", url)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun postEnergyTask(action: String, id: String? = null, packageName: String? = null, url: String? = null) {
|
||||
val taskParams = JSONObject()
|
||||
taskParams.put("action", action)
|
||||
|
||||
val actionParams = JSONObject()
|
||||
if (id != null) actionParams.put("_id", id)
|
||||
if (packageName != null) actionParams.put("package", packageName)
|
||||
if (url != null) actionParams.put("url", url)
|
||||
taskParams.put("action_param", actionParams)
|
||||
|
||||
debugOnly { Utils.log("EnergyTaskHelper -> $taskParams") }
|
||||
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), taskParams.toString())
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application)
|
||||
.api.postEnergyTask(UserManager.getInstance().userId, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<List<EnergyTaskCompleteEntity>>() {
|
||||
override fun onSuccess(data: List<EnergyTaskCompleteEntity>) {
|
||||
data.forEach { showCompletePopup(it) }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 完成弹窗
|
||||
@JvmStatic
|
||||
fun showCompletePopup(entity: EnergyTaskCompleteEntity) {
|
||||
val currentActivity = AppManager.getInstance().recentActiveActivity
|
||||
currentActivity?.run {
|
||||
val contentView = View.inflate(this, R.layout.popup_energy_task, null)
|
||||
contentView.run {
|
||||
findViewById<TextView>(R.id.taskDesc).text = "恭喜你!完成任务:${entity.name}"
|
||||
findViewById<TextView>(R.id.taskEnergy).text = "+${entity.energy}光能"
|
||||
isFocusable = true
|
||||
isFocusableInTouchMode = true
|
||||
setOnClickListener {
|
||||
currentActivity.startActivity(EnergyCenterActivity.getIntent(currentActivity))
|
||||
}
|
||||
}
|
||||
val popWindow = PopupWindow(contentView, LinearLayout.LayoutParams.MATCH_PARENT, 88F.dip2px())
|
||||
popWindow.showAtLocation(currentActivity.window.decorView, Gravity.TOP, 0, 0)
|
||||
|
||||
countDownTimer(3) { finish, _ ->
|
||||
if (finish && popWindow != null && popWindow.isShowing) {
|
||||
popWindow.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -221,6 +221,7 @@ public class EntranceUtils {
|
||||
public static final String KEY_PRIMARY_CATALOG_NAME = "primaryCatalogName";
|
||||
public static final String KEY_CATALOG_TITLE = "catalog_title";
|
||||
public static final String KEY_CATALOG_INIT_TITLE = "catalog_init_title";
|
||||
public static final String KEY_CATEGORY_LIST = "categoty_list";
|
||||
|
||||
public static void jumpActivity(Context context, Bundle bundle) {
|
||||
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
|
||||
|
||||
@ -6,6 +6,7 @@ import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.entity.ErrorEntity
|
||||
import com.lightgame.utils.Utils
|
||||
import retrofit2.HttpException
|
||||
|
||||
/**
|
||||
* 这个类用来管理一些错误,像弹窗、TOAST 什么的
|
||||
@ -169,4 +170,23 @@ object ErrorHelper {
|
||||
}, null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun handleLoginError(context: Context, httpException: HttpException?) {
|
||||
try {
|
||||
val errorEntity: ErrorEntity? = httpException?.response()?.errorBody()?.string()?.toObject()
|
||||
when {
|
||||
errorEntity?.code == 403099 -> {
|
||||
Utils.toast(context, "当前账号正在注销,禁止登录")
|
||||
}
|
||||
errorEntity?.toast?.isNotEmpty() == true -> {
|
||||
Utils.toast(context, errorEntity.toast)
|
||||
}
|
||||
else -> Utils.toast(context, R.string.login_failure)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Utils.toast(context, R.string.login_failure)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -424,7 +424,7 @@ fun String.copyTextAndToast(toastText: String = "复制成功") {
|
||||
val application = HaloApp.getInstance().application
|
||||
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText(null, this)
|
||||
cmb.primaryClip = clip
|
||||
cmb.setPrimaryClip(clip)
|
||||
|
||||
if (!TextUtils.isEmpty(toastText)) {
|
||||
ToastUtils.showToast(toastText)
|
||||
@ -602,11 +602,11 @@ fun TextView.setTextChangedListener(action: (s: CharSequence, start: Int, before
|
||||
}
|
||||
|
||||
/**
|
||||
* ArrayList related
|
||||
* List related
|
||||
*/
|
||||
fun <T> ArrayList<T>.safelyGetInRelease(index: Int): T? {
|
||||
fun <T> List<T>.safelyGetInRelease(index: Int): T? {
|
||||
return if (index >= size) {
|
||||
throwExceptionInDebug("这里触发了数组越界,请检查")
|
||||
throwExceptionInDebug("这里触发了数组越界,请检查 (index $index >= size $size)")
|
||||
toastInInternalRelease("这个操作可能触发闪退,请确定复现方式并联系开发处理")
|
||||
null
|
||||
} else {
|
||||
|
||||
@ -78,6 +78,9 @@ public class GameUtils {
|
||||
int pluginCount = 0; // 可插件化数量
|
||||
int updateCount = 0; // 可更新数量
|
||||
int installCount = 0; // 已安装数量
|
||||
|
||||
boolean isRelatedEmulatorInstalled = false; // 若该游戏是模拟器游戏时其对应的模拟器是否已经安装
|
||||
|
||||
DownloadEntity downloadEntity;
|
||||
Object gh_id;
|
||||
apkFor:
|
||||
@ -123,20 +126,26 @@ public class GameUtils {
|
||||
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(context, gameEntity.getSimulator().getApk().getPackageName());
|
||||
if (isInstalled) {
|
||||
installCount++;
|
||||
isRelatedEmulatorInstalled = true;
|
||||
} else {
|
||||
doneCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (installCount != 0) {
|
||||
|
||||
if (isRelatedEmulatorInstalled && doneCount != 0) {
|
||||
return context.getString(R.string.launch);
|
||||
}
|
||||
|
||||
if (doneCount != 0) {
|
||||
return context.getString(R.string.install);
|
||||
} 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 (installCount != 0) {
|
||||
return context.getString(R.string.launch);
|
||||
} else if (gameEntity.getVersionNumber().contains("无版号") && Config.isGameDomeSwitchOpen() && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
return context.getString(R.string.attempt);
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.database.sqlite.SQLiteFullException
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.HomePluggableFilterEntity
|
||||
import com.gh.gamecenter.room.AppDatabase
|
||||
@ -38,13 +39,18 @@ object HomePluggableHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun activationFilterData() {
|
||||
val filterList = mHomePluggableFilterDao.getDataByActive(false)
|
||||
try {
|
||||
val filterList = mHomePluggableFilterDao.getDataByActive(false)
|
||||
|
||||
if (filterList != null) {
|
||||
for (entity in filterList) {
|
||||
entity.active = true
|
||||
if (filterList != null) {
|
||||
for (entity in filterList) {
|
||||
entity.active = true
|
||||
}
|
||||
mHomePluggableFilterDao.addData(filterList)
|
||||
}
|
||||
tryCatchInRelease { mHomePluggableFilterDao.addData(filterList) }
|
||||
} catch (e: SQLiteFullException) {
|
||||
e.printStackTrace()
|
||||
toastInInternalRelease("数据库/磁盘已满,插件筛选失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -24,6 +24,7 @@ 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.facebook.imagepipeline.request.Postprocessor
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.structure.FixedSizeLinkedHashSet
|
||||
import com.gh.gamecenter.R
|
||||
@ -291,7 +292,7 @@ object ImageUtils {
|
||||
* @param isAutoPlayGif 是否禁止播放动图
|
||||
*/
|
||||
@JvmStatic
|
||||
fun display(view: SimpleDraweeView?, url: String?, isAutoPlayGif: Boolean = true) {
|
||||
fun display(view: SimpleDraweeView?, url: String?, isAutoPlayGif: Boolean = true, processor: Postprocessor? = null) {
|
||||
if (url == null) return
|
||||
|
||||
val width = view?.layoutParams?.width
|
||||
@ -310,17 +311,23 @@ object ImageUtils {
|
||||
}
|
||||
|
||||
val loadImageClosure: (autoPlay: Boolean, highResUrl: String, lowResUrl: String) -> Unit = { autoPlay, hUrl, lUrl ->
|
||||
view?.controller = Fresco.newDraweeControllerBuilder()
|
||||
.setImageRequest(ImageRequest.fromUri(hUrl))
|
||||
val imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(hUrl))
|
||||
.setPostprocessor(processor)
|
||||
.build()
|
||||
val controller = Fresco.newDraweeControllerBuilder()
|
||||
.setImageRequest(imageRequest)
|
||||
.apply {
|
||||
if (lUrl.isNotEmpty()
|
||||
&& lUrl != hUrl
|
||||
&& hUrl != view?.getTag(R.string.highResImageTag)) {
|
||||
lowResImageRequest = ImageRequest.fromUri(lUrl)
|
||||
lowResImageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(lUrl))
|
||||
.setPostprocessor(processor)
|
||||
.build()
|
||||
}
|
||||
autoPlayAnimations = autoPlay
|
||||
}
|
||||
.build()
|
||||
view?.controller = controller
|
||||
|
||||
view?.setTag(R.string.highResImageTag, highResUrl)
|
||||
}
|
||||
@ -395,6 +402,18 @@ object ImageUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已缓存的图片地址,不区分质量,暂时只供查看大图页面使用
|
||||
*/
|
||||
fun getCachedUrl(url: String): String {
|
||||
for (decoratedUrl in mImageUrlCacheSet) {
|
||||
if (decoratedUrl.contains(url)) {
|
||||
return decoratedUrl
|
||||
}
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun bmpToByteArray(bmp: Bitmap, needRecycle: Boolean): ByteArray {
|
||||
val output = ByteArrayOutputStream()
|
||||
|
||||
@ -18,11 +18,11 @@ public class Installation {
|
||||
private static String sID = null;
|
||||
|
||||
public synchronized static String getUUID(Context context) {
|
||||
String imei = MetaUtil.getIMEI();
|
||||
String imei = MetaUtil.getBase64EncodedIMEI();
|
||||
if (!TextUtils.isEmpty(imei)) {
|
||||
return imei;
|
||||
}
|
||||
String android_id = MetaUtil.getAndroidId();
|
||||
String android_id = MetaUtil.getBase64EncodedAndroidId();
|
||||
if (!TextUtils.isEmpty(android_id)) {
|
||||
return android_id;
|
||||
}
|
||||
|
||||
@ -235,6 +235,7 @@ public class LogUtils {
|
||||
object.put("game_name", gameEntity.getName());
|
||||
object.put("game_id", gameEntity.getId());
|
||||
object.put("game_platform", gameEntity.getPlatform());
|
||||
object.put("download_open", gameEntity.getDownloadOffStatus() == null ? "true" : "false");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -255,13 +256,13 @@ public class LogUtils {
|
||||
try {
|
||||
object.put("version", PackageUtils.getVersionName());
|
||||
object.put("channel", HaloApp.getInstance().getChannel());
|
||||
object.put("android_id", MetaUtil.getAndroidId());
|
||||
object.put("dia", MetaUtil.getBase64EncodedAndroidId());
|
||||
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", MetaUtil.getIMEI());
|
||||
object.put("jnfj", MetaUtil.getBase64EncodedIMEI());
|
||||
object.put("G_ID", UserManager.getInstance().getDeviceId());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
@ -279,13 +280,13 @@ public class LogUtils {
|
||||
try {
|
||||
object.put("version", PackageUtils.getVersionName());
|
||||
object.put("channel", HaloApp.getInstance().getChannel());
|
||||
object.put("android_id", MetaUtil.getAndroidId());
|
||||
object.put("dia", MetaUtil.getBase64EncodedAndroidId());
|
||||
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", MetaUtil.getIMEI());
|
||||
object.put("jnfj", MetaUtil.getBase64EncodedIMEI());
|
||||
object.put("G_ID", UserManager.getInstance().getDeviceId());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
@ -298,13 +299,13 @@ public class LogUtils {
|
||||
Meta meta = MetaUtil.INSTANCE.getMeta();
|
||||
JSONObject metaObject = new JSONObject();
|
||||
try {
|
||||
metaObject.put("android_id", meta.getAndroid_id());
|
||||
metaObject.put("dia", MetaUtil.getBase64EncodedAndroidId());
|
||||
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("jnfj", MetaUtil.getBase64EncodedIMEI());
|
||||
metaObject.put("mac", meta.getMac());
|
||||
metaObject.put("manufacturer", meta.getManufacturer());
|
||||
metaObject.put("model", meta.getModel());
|
||||
@ -429,13 +430,13 @@ public class LogUtils {
|
||||
Meta meta = MetaUtil.INSTANCE.getMeta();
|
||||
JSONObject metaObject = new JSONObject();
|
||||
try {
|
||||
metaObject.put("android_id", meta.getAndroid_id());
|
||||
metaObject.put("dia", MetaUtil.getBase64EncodedAndroidId());
|
||||
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("jnfj", MetaUtil.getBase64EncodedIMEI());
|
||||
metaObject.put("mac", meta.getMac());
|
||||
metaObject.put("manufacturer", meta.getManufacturer());
|
||||
metaObject.put("model", meta.getModel());
|
||||
@ -523,13 +524,13 @@ public class LogUtils {
|
||||
Meta meta = MetaUtil.INSTANCE.getMeta();
|
||||
JSONObject metaObject = new JSONObject();
|
||||
try {
|
||||
metaObject.put("android_id", meta.getAndroid_id());
|
||||
metaObject.put("dia", MetaUtil.getBase64EncodedAndroidId());
|
||||
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("jnfj", MetaUtil.getBase64EncodedIMEI());
|
||||
metaObject.put("mac", meta.getMac());
|
||||
metaObject.put("manufacturer", meta.getManufacturer());
|
||||
metaObject.put("model", meta.getModel());
|
||||
@ -612,10 +613,16 @@ public class LogUtils {
|
||||
}
|
||||
|
||||
public static void uploadSearchGame(String event, String location, String key, String searchType) {
|
||||
uploadSearchClick(event, location, key, searchType, "", "");
|
||||
uploadSearchClick(event, location, key, searchType, "", "", false);
|
||||
}
|
||||
|
||||
public static void uploadSearchClick(String event, String location, String key, String searchType, String gameId, String gameName) {
|
||||
public static void uploadSearchClick(String event,
|
||||
String location,
|
||||
String key,
|
||||
String searchType,
|
||||
String gameId,
|
||||
String gameName,
|
||||
Boolean isMirrorData) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payload = new JSONObject();
|
||||
try {
|
||||
@ -628,6 +635,7 @@ public class LogUtils {
|
||||
payload.put("search_type", searchType); //搜索类型, 有四种取值 默认搜索/历史搜索/自动搜索/主动搜索
|
||||
payload.put("game_id", gameId); //event为search_click才取值
|
||||
payload.put("game_name", gameName); //event为search_click才取值
|
||||
payload.put("is_mirror_data", isMirrorData);
|
||||
object.put("payload", payload);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@ -86,13 +86,17 @@ public class MessageShareUtils {
|
||||
@Override
|
||||
public void onError(UiError uiError) {
|
||||
// 单分享图片不支持显示未安装弹窗,手动调出
|
||||
Activity activity = mActivity.get();
|
||||
if (activity != null && !ShareUtils.isQQClientAvailable(activity.getApplication())) {
|
||||
new TDialog(activity,
|
||||
"",
|
||||
"http://openmobile.qq.com/oauth2.0/m_jump_by_version",
|
||||
null,
|
||||
new QQToken("")).show();
|
||||
if (mActivity != null) {
|
||||
Activity activity = mActivity.get();
|
||||
if (activity != null && !ShareUtils.isQQClientAvailable(activity.getApplication())) {
|
||||
new TDialog(activity,
|
||||
"",
|
||||
"http://openmobile.qq.com/oauth2.0/m_jump_by_version",
|
||||
null,
|
||||
new QQToken("")).show();
|
||||
} else {
|
||||
Utils.toast(mContext, "分享失败");
|
||||
}
|
||||
} else {
|
||||
Utils.toast(mContext, "分享失败");
|
||||
}
|
||||
|
||||
@ -37,4 +37,15 @@ object NumberUtils {
|
||||
val minute = Math.round((totalMinute - hour * 60).toFloat())
|
||||
return hour.toString() + "小时" + if (minute == 0) "" else minute.toString() + "分钟"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun findMax(lastPositions: IntArray): Int {
|
||||
var max = lastPositions[0]
|
||||
for (value in lastPositions) {
|
||||
if (value > max) {
|
||||
max = value
|
||||
}
|
||||
}
|
||||
return max
|
||||
}
|
||||
}
|
||||
@ -26,8 +26,8 @@ object PackageInstaller {
|
||||
* 为了兼容java代码
|
||||
*/
|
||||
@JvmStatic
|
||||
fun install(context: Context, downloadEntity: DownloadEntity) {
|
||||
install(context, downloadEntity, true)
|
||||
fun install(context: Context, downloadEntity: DownloadEntity?) {
|
||||
downloadEntity?.let { install(context, downloadEntity, true) }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,15 +44,19 @@ object PackageInstaller {
|
||||
|
||||
val currentActivity = AppManager.getInstance().currentActivity() ?: return
|
||||
|
||||
InstallPermissionDialogFragment.show(currentActivity as AppCompatActivity, downloadEntity) {
|
||||
// 取消状态栏下载完成的通知,若存在
|
||||
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
// TODO 此处可能遇到 activity 是 WXEntryActivity
|
||||
// TODO 当 activity 全部出栈,但是应用还在下载游戏,下载完会唤不起安装!
|
||||
if (currentActivity is AppCompatActivity) {
|
||||
InstallPermissionDialogFragment.show(currentActivity, downloadEntity) {
|
||||
// 取消状态栏下载完成的通知,若存在
|
||||
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
|
||||
if (isXapk) {
|
||||
XapkInstaller.install(context, downloadEntity, showUnzipToast)
|
||||
} else {
|
||||
install(context, downloadEntity.path)
|
||||
if (isXapk) {
|
||||
XapkInstaller.install(context, downloadEntity, showUnzipToast)
|
||||
} else {
|
||||
install(context, downloadEntity.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,16 +183,13 @@ public class PackageUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO 找一个更好的办法来比较签名并且不触发 ANR
|
||||
public static boolean compareSignatureBetweenInstalledAppWithApk(Context context, String packageName, String apkFilePath) {
|
||||
try {
|
||||
// 统计签名比较使用的频率 (大文件会触发 ANR)
|
||||
SentryHelper.INSTANCE.onEvent(
|
||||
"SIGNATURE_COMPARE",
|
||||
"packageName", packageName);
|
||||
|
||||
// 据 Sentry 统计,刚上架一个周末的包里对这个方法有 700+ 次调用,然后其中一部分会造成 ANR
|
||||
Signature sig = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures[0];
|
||||
|
||||
// Fuck HUAWEI, 华为系统调用 getPackageArchiveInfo 获取魔羯 apk 的签名时会耗时超过5秒造成 ANR,没有找到解决方法
|
||||
// 调用 getPackageArchiveInfo 获取较大的 apk 的签名时会耗时超过5秒造成 ANR,没有找到解决方法
|
||||
// 如果可以的话尽量避免调用 getPackageArchiveInfo 方法
|
||||
Signature releaseSig = context.getPackageManager().getPackageArchiveInfo(apkFilePath, PackageManager.GET_SIGNATURES).signatures[0];
|
||||
return sig.hashCode() == releaseSig.hashCode();
|
||||
@ -519,15 +516,21 @@ public class PackageUtils {
|
||||
* @return 进程名
|
||||
*/
|
||||
public static String obtainProcessName(Context context) {
|
||||
final int pid = android.os.Process.myPid();
|
||||
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
List<ActivityManager.RunningAppProcessInfo> listTaskInfo = am.getRunningAppProcesses();
|
||||
if (listTaskInfo != null && !listTaskInfo.isEmpty()) {
|
||||
for (ActivityManager.RunningAppProcessInfo info : listTaskInfo) {
|
||||
if (info != null && info.pid == pid) {
|
||||
return info.processName;
|
||||
try {
|
||||
final int pid = android.os.Process.myPid();
|
||||
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
List<ActivityManager.RunningAppProcessInfo> listTaskInfo = am.getRunningAppProcesses();
|
||||
if (listTaskInfo != null && !listTaskInfo.isEmpty()) {
|
||||
for (ActivityManager.RunningAppProcessInfo info : listTaskInfo) {
|
||||
if (info != null && info.pid == pid) {
|
||||
return info.processName;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 遇到异常了让这次调用正常执行
|
||||
e.printStackTrace();
|
||||
return BuildConfig.APPLICATION_ID;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -64,34 +64,24 @@ object ReservationHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun showDeleteReservationDialog(context: Context, emptyCallback: EmptyCallback) {
|
||||
DialogHelper.showDialog(
|
||||
context,
|
||||
DialogUtils.showCancelOrDeleteReservationDialog(context,
|
||||
"删除预约",
|
||||
"游戏已上线,你可以删除此预约记录,确定删除吗?",
|
||||
"确定删除",
|
||||
"暂不删除",
|
||||
{ emptyCallback.onCallback() },
|
||||
null,
|
||||
trackMtaEvent = true
|
||||
// , mtaEvent = "预约游戏",
|
||||
// mtaKey = "删除预约弹窗"
|
||||
)
|
||||
"暂不删除", {
|
||||
emptyCallback.onCallback()
|
||||
}, null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun showCancelReservationDialog(context: Context, emptyCallback: EmptyCallback) {
|
||||
DialogHelper.showDialog(
|
||||
context,
|
||||
DialogUtils.showCancelOrDeleteReservationDialog(context,
|
||||
"取消预约",
|
||||
"取消之后你将无法收到游戏上线的通知,确定取消预约吗?",
|
||||
"确定取消",
|
||||
"暂不取消",
|
||||
{ emptyCallback.onCallback() },
|
||||
null,
|
||||
trackMtaEvent = true
|
||||
// , mtaEvent = "预约游戏",
|
||||
// mtaKey = "取消预约弹窗"
|
||||
)
|
||||
"暂不取消", {
|
||||
emptyCallback.onCallback()
|
||||
}, null)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -124,6 +124,7 @@ public class ShareUtils {
|
||||
EventBus.getDefault().post(new EBShare(ShareUtils.shareEntrance));
|
||||
LogUtils.uploadShareResult(shareType, ShareUtils.shareEntrance.getName(), "success",
|
||||
ShareUtils.shareEntity.getShareUrl(), ShareUtils.shareEntity.getShareTitle(), ShareUtils.shareEntity.getSummary(), ShareUtils.resourceId);
|
||||
EnergyTaskHelper.postEnergyTaskForShare(ShareUtils.shareEntrance.getName(), ShareUtils.resourceId, ShareUtils.shareEntity.getShareUrl());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -318,13 +319,27 @@ public class ShareUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public void shareGameDetail(Activity activity, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id, ShareCallBack callBack) {
|
||||
if (activity.isFinishing()) return;
|
||||
this.mActivity = new WeakReference<>(activity);
|
||||
this.shareIcon = icon;
|
||||
this.shareUrl = url;
|
||||
this.mSummary = shareSummary;
|
||||
this.mTitle = shareTitle;
|
||||
this.mShareEntrance = shareEntrance;
|
||||
ShareUtils.shareEntrance = mShareEntrance;
|
||||
ShareUtils.resourceId = id;
|
||||
ShareUtils.shareEntity = new ShareEntity(shareUrl, mTitle, mSummary);
|
||||
LogUtils.uploadShareEnter(mShareEntrance.getName(), shareUrl, mTitle, mSummary, id);
|
||||
}
|
||||
|
||||
|
||||
public void showShareWindows(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id) {
|
||||
showShareWindowsCallback(activity, view, url, icon, shareTitle, shareSummary, shareEntrance, id, null);
|
||||
}
|
||||
|
||||
//QQ分享
|
||||
private void qqShare() {
|
||||
public void qqShare() {
|
||||
Utils.toast(mContext, R.string.share_skip);
|
||||
Bundle params = new Bundle();
|
||||
|
||||
@ -359,7 +374,7 @@ public class ShareUtils {
|
||||
}
|
||||
|
||||
//微信好友分享
|
||||
private void wechatShare() {
|
||||
public void wechatShare() {
|
||||
Utils.toast(mContext, R.string.share_skip);
|
||||
|
||||
if (!PackageHelper.INSTANCE.getLocalPackageNameSet().contains("com.tencent.mm")) {
|
||||
@ -476,7 +491,7 @@ public class ShareUtils {
|
||||
}
|
||||
|
||||
//QQ空间分享
|
||||
private void qZoneShare() {
|
||||
public void qZoneShare() {
|
||||
Utils.toast(mContext, R.string.share_skip);
|
||||
Bundle params = new Bundle();
|
||||
|
||||
@ -515,7 +530,7 @@ public class ShareUtils {
|
||||
}
|
||||
|
||||
//微信朋友圈分享
|
||||
private void wechatMomentsShare() {
|
||||
public void wechatMomentsShare() {
|
||||
Utils.toast(mContext, R.string.share_skip);
|
||||
|
||||
if (!PackageHelper.INSTANCE.getLocalPackageNameSet().contains("com.tencent.mm")) {
|
||||
@ -558,7 +573,7 @@ public class ShareUtils {
|
||||
}
|
||||
|
||||
//新浪微博分享
|
||||
private void sinaWeiboShare() {
|
||||
public void sinaWeiboShare() {
|
||||
WbSdk.install(mContext, new AuthInfo(mContext, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE));
|
||||
|
||||
if (mShareEntrance == ShareEntrance.qaDetail) {
|
||||
@ -584,7 +599,7 @@ public class ShareUtils {
|
||||
}
|
||||
|
||||
//短信分享
|
||||
private void shortMessageShare() {
|
||||
public void shortMessageShare() {
|
||||
String smsBody;
|
||||
switch (mShareEntrance) {
|
||||
case news:
|
||||
@ -628,7 +643,7 @@ public class ShareUtils {
|
||||
}
|
||||
|
||||
//复制文字链接
|
||||
private void copyLink(String copyContent) {
|
||||
public void copyLink(String copyContent) {
|
||||
shareType = "copy_link";
|
||||
LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
|
||||
if (mShareEntrance != ShareEntrance.shareGh) {
|
||||
@ -664,6 +679,7 @@ public class ShareUtils {
|
||||
if (listener != null) {
|
||||
listener.onItemClick(holder.getAdapterPosition());
|
||||
}
|
||||
|
||||
switch (holder.getPosition()) {
|
||||
case 0:
|
||||
shareType = "wechat_friend";
|
||||
@ -749,7 +765,7 @@ public class ShareUtils {
|
||||
}
|
||||
|
||||
private void safelyDismiss() {
|
||||
if (popupWindow.get() != null) {
|
||||
if (popupWindow != null && popupWindow.get() != null) {
|
||||
popupWindow.get().dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ object SPUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun getString(key: String): String {
|
||||
return sp.getString(key, "")
|
||||
return sp.getString(key, "")?:""
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@ -71,7 +71,7 @@ object SyncDataBetweenPageHelper {
|
||||
val fields = syncData::class.java.declaredFields
|
||||
var isNeedNotify = false
|
||||
for (field in fields) {
|
||||
if (field.getAnnotation(Synchronize::class.java) != null) {
|
||||
if (field.getAnnotation(Synchronize::class.java) != null && resultData != null) {
|
||||
// 同步数据
|
||||
val resultField = resultData::class.java.getDeclaredField(field.name)
|
||||
resultField.isAccessible = true
|
||||
|
||||
@ -117,6 +117,17 @@ object TimeUtils {
|
||||
return calendar.timeInMillis
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getTimeOfToday(hour: Int): Long {
|
||||
val calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"))
|
||||
calendar.timeInMillis = getJavaTimestamp(System.currentTimeMillis())
|
||||
calendar.set(Calendar.HOUR_OF_DAY, hour)
|
||||
calendar.set(Calendar.MINUTE, 0)
|
||||
calendar.set(Calendar.SECOND, 0)
|
||||
calendar.set(Calendar.MILLISECOND, 0)
|
||||
return calendar.timeInMillis
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getJavaTimestamp(timestamp: Long): Long {
|
||||
return if ((log10(timestamp.toDouble()) + 1).toInt() == 10) {
|
||||
|
||||
@ -6,6 +6,7 @@ import com.gh.common.constant.Constants;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.halo.assistant.HaloApp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import androidx.collection.ArrayMap;
|
||||
@ -17,10 +18,12 @@ public class TimestampUtils {
|
||||
|
||||
private static ArrayMap<String, Integer> intervalMap; // 间隔
|
||||
private static ArrayMap<String, Integer> cdMap; // cd
|
||||
private static ArrayList<String> whiteList; // 白名单
|
||||
|
||||
public static void initMap() {
|
||||
initIntervalMap();
|
||||
initCDMap();
|
||||
initWhiteList();
|
||||
}
|
||||
|
||||
private static void initIntervalMap() {
|
||||
@ -43,11 +46,25 @@ public class TimestampUtils {
|
||||
cdMap.put(".*packages.*", Constants.PACKAGES_CD);
|
||||
}
|
||||
|
||||
private static void initWhiteList() {
|
||||
whiteList = new ArrayList<>();
|
||||
whiteList.add(".*tasks:check.*");
|
||||
whiteList.add(".*novice_tasks.*");
|
||||
whiteList.add(".*daily_tasks.*");
|
||||
whiteList.add(".*energies.*");
|
||||
}
|
||||
|
||||
/*
|
||||
* 为url添加timestamp
|
||||
*/
|
||||
public static String addTimestamp(String url) {
|
||||
|
||||
for (String key : whiteList) {
|
||||
if (Pattern.matches(key, url)) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG || "GH_REFRESH".equals(HaloApp.getInstance().getChannel())) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return url;
|
||||
|
||||
21
app/src/main/java/com/gh/common/util/TopCutProcess.kt
Normal file
21
app/src/main/java/com/gh/common/util/TopCutProcess.kt
Normal file
@ -0,0 +1,21 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Matrix
|
||||
import com.facebook.common.references.CloseableReference
|
||||
import com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory
|
||||
import com.facebook.imagepipeline.request.BasePostprocessor
|
||||
|
||||
class TopCutProcess(private val cutRatio: Float) : BasePostprocessor() {
|
||||
|
||||
override fun process(sourceBitmap: Bitmap, bitmapFactory: PlatformBitmapFactory): CloseableReference<Bitmap>? {
|
||||
val viewWidth = sourceBitmap.width
|
||||
val viewHeight = sourceBitmap.height.toFloat()
|
||||
var newHeight = viewWidth / cutRatio
|
||||
if (newHeight > viewHeight) {
|
||||
newHeight = viewHeight
|
||||
}
|
||||
val bitmapRef = bitmapFactory.createBitmap(sourceBitmap, 0, 0, viewWidth, (newHeight).toInt())
|
||||
return CloseableReference.cloneOrNull(bitmapRef)
|
||||
}
|
||||
}
|
||||
@ -1,127 +0,0 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.MediaStore;
|
||||
|
||||
public class UriUtils {
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public static String getPath(final Context context, final Uri uri) {
|
||||
|
||||
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
||||
|
||||
// DocumentProvider
|
||||
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
||||
// ExternalStorageProvider
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
final String docId = DocumentsContract.getDocumentId(uri);
|
||||
final String[] split = docId.split(":");
|
||||
final String type = split[0];
|
||||
|
||||
if ("primary".equalsIgnoreCase(type)) {
|
||||
return Environment.getExternalStorageDirectory() + "/" + split[1];
|
||||
}
|
||||
}
|
||||
// DownloadsProvider
|
||||
else if (isDownloadsDocument(uri)) {
|
||||
|
||||
final String id = DocumentsContract.getDocumentId(uri);
|
||||
final Uri contentUri = ContentUris.withAppendedId(
|
||||
Uri.parse("content://downloads/public_downloads"), Long.parseLong(id));
|
||||
|
||||
return getDataColumn(context, contentUri, null, null);
|
||||
}
|
||||
// MediaProvider
|
||||
else if (isMediaDocument(uri)) {
|
||||
final String docId = DocumentsContract.getDocumentId(uri);
|
||||
final String[] split = docId.split(":");
|
||||
final String type = split[0];
|
||||
|
||||
Uri contentUri = null;
|
||||
if ("image".equals(type)) {
|
||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("video".equals(type)) {
|
||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("audio".equals(type)) {
|
||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
}
|
||||
|
||||
final String selection = "_id=?";
|
||||
final String[] selectionArgs = new String[]{split[1]};
|
||||
|
||||
return getDataColumn(context, contentUri, selection, selectionArgs);
|
||||
}
|
||||
}
|
||||
// MediaStore (and general)
|
||||
else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
||||
return getDataColumn(context, uri, null, null);
|
||||
}
|
||||
// File
|
||||
else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
||||
return uri.getPath();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the data column for this Uri. This is useful for
|
||||
* MediaStore Uris, and other file-based ContentProviders.
|
||||
*
|
||||
* @param context The context.
|
||||
* @param uri The Uri to query.
|
||||
* @param selection (Optional) Filter used in the query.
|
||||
* @param selectionArgs (Optional) Selection arguments used in the query.
|
||||
* @return The value of the _data column, which is typically a file path.
|
||||
*/
|
||||
private static String getDataColumn(Context context, Uri uri, String selection,
|
||||
String[] selectionArgs) {
|
||||
|
||||
Cursor cursor = null;
|
||||
final String column = "_data";
|
||||
final String[] projection = {column};
|
||||
|
||||
try {
|
||||
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
|
||||
null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
final int column_index = cursor.getColumnIndexOrThrow(column);
|
||||
return cursor.getString(column_index);
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The Uri to check.
|
||||
* @return Whether the Uri authority is ExternalStorageProvider.
|
||||
*/
|
||||
private static boolean isExternalStorageDocument(Uri uri) {
|
||||
return "com.android.externalstorage.documents".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The Uri to check.
|
||||
* @return Whether the Uri authority is DownloadsProvider.
|
||||
*/
|
||||
private static boolean isDownloadsDocument(Uri uri) {
|
||||
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The Uri to check.
|
||||
* @return Whether the Uri authority is MediaProvider.
|
||||
*/
|
||||
private static boolean isMediaDocument(Uri uri) {
|
||||
return "com.android.providers.media.documents".equals(uri.getAuthority());
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,7 @@ import android.app.AppOpsManager.MODE_ALLOWED
|
||||
import android.app.AppOpsManager.OPSTR_GET_USAGE_STATS
|
||||
import android.app.usage.UsageEvents
|
||||
import android.app.usage.UsageStatsManager
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
@ -257,10 +258,15 @@ object UsageStatsHelper {
|
||||
@JvmStatic
|
||||
fun skipToUsageStats(context: Context, requestCode: Int = -1) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (context is Activity && requestCode != -1) {
|
||||
context.startActivityForResult(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS), requestCode)
|
||||
} else {
|
||||
context.startActivity(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS))
|
||||
try {
|
||||
if (context is Activity && requestCode != -1) {
|
||||
context.startActivityForResult(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS), requestCode)
|
||||
} else {
|
||||
context.startActivity(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS))
|
||||
}
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
Utils.toast(context, "当前设备不支持直接跳转查看应用使用情况页面,请手动进入并打开")
|
||||
e.printStackTrace()
|
||||
}
|
||||
} else {
|
||||
Utils.toast(context, "当前设备不支持查看应用使用情况")
|
||||
|
||||
@ -2,7 +2,10 @@ package com.gh.common.videolog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import android.database.sqlite.SQLiteFullException
|
||||
import com.gh.common.util.toRequestBody
|
||||
import com.gh.common.util.toastInInternalRelease
|
||||
import com.gh.common.util.tryWithDefaultCatch
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
@ -26,8 +29,10 @@ object VideoRecordUtils {
|
||||
mApplication = application
|
||||
|
||||
videoRecordExecutor.execute {
|
||||
val recordList = videoRecordDao.getAll()
|
||||
videoRecordSet.addAll(recordList)
|
||||
tryWithDefaultCatch {
|
||||
val recordList = videoRecordDao.getAll()
|
||||
videoRecordSet.addAll(recordList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +44,9 @@ object VideoRecordUtils {
|
||||
videoRecordDao.insert(entity)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (e is SQLiteFullException) {
|
||||
toastInInternalRelease("数据库/磁盘已满,写入视频新日志失败")
|
||||
}
|
||||
}
|
||||
if (videoRecordSet.size >= STORE_SIZE) {
|
||||
commitVideoRecord()
|
||||
@ -52,7 +60,11 @@ object VideoRecordUtils {
|
||||
uploadVideoRecord()
|
||||
val exposureList = videoRecordSet.toList()
|
||||
videoRecordSet.removeAll(exposureList)
|
||||
videoRecordDao.deleteMany(exposureList)
|
||||
try {
|
||||
videoRecordDao.deleteMany(exposureList)
|
||||
} catch (e: SQLiteFullException) {
|
||||
toastInInternalRelease("数据库/磁盘已满,删除视频日志失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import android.graphics.drawable.PaintDrawable
|
||||
import android.view.View
|
||||
import android.widget.PopupWindow
|
||||
|
||||
class BugFixedPopupWindow @JvmOverloads constructor(contentView: View? = null, width: Int = 0, height: Int = 0)
|
||||
open class BugFixedPopupWindow @JvmOverloads constructor(contentView: View? = null, width: Int = 0, height: Int = 0)
|
||||
: PopupWindow(contentView, width, height) {
|
||||
|
||||
init {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.gh.common.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.RectF
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewConfiguration
|
||||
@ -37,7 +38,9 @@ class DraggableBigImageView @JvmOverloads constructor(context: Context, attrs: A
|
||||
MotionEvent.ACTION_DOWN -> if (mInitScale == null || mInitScale == 0F) mInitScale = ssiv?.scale
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> up()
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
if (mSingleTouch && mInitScale != 0F && ssiv?.scale == mInitScale) {
|
||||
val rectF = RectF()
|
||||
ssiv?.getPanRemaining(rectF)
|
||||
if (mSingleTouch && mInitScale != 0F && (rectF.top == 0f || rectF.bottom == 0f)) {
|
||||
if (mLastX == 0F) mLastX = event.rawX
|
||||
if (mLastY == 0F) mLastY = event.rawY
|
||||
val offsetX = event.rawX - mLastX
|
||||
|
||||
@ -100,7 +100,8 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
|
||||
/**
|
||||
* 适用于不使用 maxLines 而是整段收起时的文字来确定“...更多”的位置的样式
|
||||
* @param shrankText 收起时的文字 (“...更多”跟在 shrankText 后)
|
||||
*
|
||||
* @param shrankText 收起时的文字 (“...更多”跟在 shrankText 后)
|
||||
* @param expandedText 展开时的文字
|
||||
*/
|
||||
public void setShrankTextAndExpandedText(CharSequence shrankText, CharSequence expandedText) {
|
||||
@ -122,6 +123,11 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
}
|
||||
|
||||
private void showExpandButton() {
|
||||
// 避免二次生成展开按钮 (有点粗暴,但是为了满足 recyclerView 复用后没问题,还是每次都用当前文字来判断比较好)
|
||||
if (getText().toString().endsWith(mExpandText)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String finalEndText = "";
|
||||
TextPaint paint = getPaint();
|
||||
|
||||
@ -160,6 +166,10 @@ public class ExpandTextView extends AppCompatTextView {
|
||||
float subSequenceWidth;
|
||||
for (int i = lastLineText.length() - 1; i > 0; i--) {
|
||||
if (mUseGradientAlphaEndText) {
|
||||
|
||||
// 避免 additionalEntTextCount 大于 i 造成数组越界 (TODO 代码太多,有时间再检查)
|
||||
if (additionalEndTextCount > i) return;
|
||||
|
||||
subSequence = lastLineText.subSequence(0, i - additionalEndTextCount);
|
||||
subSequenceWidth = paint.measureText(subSequence.toString());
|
||||
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
package com.gh.common.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class FixGridLayoutManager extends GridLayoutManager {
|
||||
|
||||
|
||||
public FixGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
public FixGridLayoutManager(Context context, int spanCount) {
|
||||
super(context, spanCount);
|
||||
}
|
||||
|
||||
public FixGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
|
||||
super(context, spanCount, orientation, reverseLayout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
|
||||
try {
|
||||
super.onLayoutChildren(recycler, state);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.widget.ScrollView
|
||||
import java.lang.IllegalArgumentException
|
||||
|
||||
/**
|
||||
* 不能滑动的 ScrollView
|
||||
@ -11,10 +12,16 @@ import android.widget.ScrollView
|
||||
class FixedScrollView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : ScrollView(context, attrs) {
|
||||
|
||||
override fun onTouchEvent(ev: MotionEvent?): Boolean {
|
||||
return when (ev?.action) {
|
||||
MotionEvent.ACTION_DOWN -> true
|
||||
else -> super.onTouchEvent(ev)
|
||||
// super.onTouchEvent may cause IllegalArgumentException which is crazy!
|
||||
try {
|
||||
return when (ev?.action) {
|
||||
MotionEvent.ACTION_DOWN -> true
|
||||
else -> super.onTouchEvent(ev)
|
||||
}
|
||||
} catch (e: IllegalArgumentException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
|
||||
|
||||
@ -20,7 +20,7 @@ class GradientAlphaTextSpan(var textColor: Int) : ReplacementSpan() {
|
||||
originalColor, originalColorWithAlphaChanged, Shader.TileMode.CLAMP)
|
||||
paint.shader = mShader
|
||||
|
||||
canvas.drawText(text, start, end, x, y.toFloat(), paint)
|
||||
canvas.drawText(text ?: "", start, end, x, y.toFloat(), paint)
|
||||
|
||||
paint.shader = null
|
||||
}
|
||||
|
||||
221
app/src/main/java/com/gh/common/view/ImageContainerView.kt
Normal file
221
app/src/main/java/com/gh/common/view/ImageContainerView.kt
Normal file
@ -0,0 +1,221 @@
|
||||
package com.gh.common.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.facebook.drawee.drawable.ScalingUtils
|
||||
import com.gh.common.util.*
|
||||
import com.gh.gamecenter.ImageViewerActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.databinding.ItemCommunityImageBinding
|
||||
import com.gh.gamecenter.qa.entity.AnswerEntity
|
||||
import com.gh.gamecenter.qa.entity.CommunityVideoEntity
|
||||
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
|
||||
import java.util.ArrayList
|
||||
|
||||
class ImageContainerView : LinearLayout {
|
||||
private var mAnswerEntity: AnswerEntity? = null
|
||||
|
||||
//三图默认宽度
|
||||
private var mDefaultWidth = 0f
|
||||
|
||||
//单图固定宽度
|
||||
private var mFixdWidth = 0f
|
||||
|
||||
//最小比例
|
||||
private var mMinRatio = 3 / 4f
|
||||
|
||||
//最大比例
|
||||
private var mMaxRatio = 3 / 2f
|
||||
|
||||
//长图比例
|
||||
private var mLongPictureRatio = 9 / 18f
|
||||
|
||||
private var mEntrance = ""
|
||||
private var mPath = ""
|
||||
|
||||
//图片之间的间距
|
||||
private val mItemSpace = 4f.dip2px()
|
||||
private var index = 0
|
||||
|
||||
constructor(context: Context) : this(context, null)
|
||||
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
|
||||
initView(attrs)
|
||||
}
|
||||
|
||||
private fun initView(attrs: AttributeSet?) {
|
||||
orientation = HORIZONTAL
|
||||
val ta = context.obtainStyledAttributes(attrs, R.styleable.ImageContainerView)
|
||||
val offset = ta.getDimensionPixelSize(R.styleable.ImageContainerView_offset, 0)
|
||||
mDefaultWidth = (DisplayUtils.getScreenWidth() - offset.toFloat() - mItemSpace * 2) / 3
|
||||
mFixdWidth = (DisplayUtils.getScreenWidth() - offset.toFloat() - mItemSpace * 2) * 2 / 3
|
||||
ta.recycle()
|
||||
}
|
||||
|
||||
fun bindData(entity: AnswerEntity, entrance: String = "", path: String = "") {
|
||||
mAnswerEntity = entity
|
||||
mEntrance = entrance
|
||||
mPath = path
|
||||
index = 0
|
||||
removeAllViews()
|
||||
if (entity.getPassVideos().isNullOrEmpty() && entity.images.isNullOrEmpty()) {
|
||||
visibility = View.GONE
|
||||
return
|
||||
}
|
||||
visibility = View.VISIBLE
|
||||
if (mAnswerEntity?.type == "community_article") {
|
||||
//若文章内容含有图片及视频,则信息流卡片,仅展示图片,且标题后带有‘有视频’标签
|
||||
//若文章内容仅含有图片,则信息流卡片,仅展示图片,无标签
|
||||
//若文章内容仅含有视频,则信息流卡片,仅展示视频,无标签
|
||||
when {
|
||||
entity.images.isNotEmpty() -> {
|
||||
val imagesInfo = entity.imagesInfo
|
||||
val images = entity.images.take(3)
|
||||
images.forEachIndexed { index, url ->
|
||||
val width = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].width else 0
|
||||
val height = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].height else 0
|
||||
bindImage(url, width, height, images.size == 1)
|
||||
}
|
||||
}
|
||||
entity.getPassVideos().isNotEmpty() -> {
|
||||
val video = entity.getPassVideos()[0]
|
||||
bindVideo(video, video.width, video.height, true)
|
||||
}
|
||||
else -> {
|
||||
// do noting
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//若问答内容含有图片及视频,则信息流卡片,同时展示图片及视频,且参考以往排序逻辑(视频优先放置第一位),无标签
|
||||
//若问答内容仅含有图片,则信息流卡片,仅展示图片,无标签
|
||||
//若问答内容仅含有视频,则信息流卡片,仅展示视频,无标签
|
||||
if (entity.getPassVideos().isNotEmpty()) {
|
||||
val video = entity.getPassVideos()[0]
|
||||
bindVideo(video, video.width, video.height, mAnswerEntity?.images.isNullOrEmpty())
|
||||
entity.images.take(2).forEachIndexed { index, url ->
|
||||
val imagesInfo = entity.imagesInfo
|
||||
val width = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].width else 0
|
||||
val height = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].height else 0
|
||||
bindImage(url, width, height, false)
|
||||
}
|
||||
} else {
|
||||
val images = entity.images.take(3)
|
||||
images.forEachIndexed { index, url ->
|
||||
val imagesInfo = entity.imagesInfo
|
||||
val width = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].width else 0
|
||||
val height = if (index <= entity.imagesInfo.size - 1) imagesInfo[index].height else 0
|
||||
bindImage(url, width, height, images.size == 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindVideo(video: CommunityVideoEntity, width: Int, height: Int, isChangeRatio: Boolean) {
|
||||
val binding = ItemCommunityImageBinding.inflate(LayoutInflater.from(context), null, false)
|
||||
addView(binding.root)
|
||||
binding.durationOrNumTv.visibility = View.VISIBLE
|
||||
binding.videoPlay.visibility = View.VISIBLE
|
||||
binding.labelIcon.visibility = View.GONE
|
||||
binding.durationOrNumTv.text = video.duration
|
||||
displayImage(binding, video.poster, width.toFloat(), height.toFloat(), isChangeRatio, true)
|
||||
binding.root.setOnClickListener {
|
||||
debounceActionWithInterval(it.id, 1000) {
|
||||
if (mAnswerEntity == null) return@debounceActionWithInterval
|
||||
val videoEntity = mAnswerEntity!!.getPassVideos()[0]
|
||||
DirectUtils.directToVideoDetail(context,
|
||||
videoEntity.id,
|
||||
VideoDetailContainerViewModel.Location.VIDEO_HOT.value,
|
||||
showComment = false,
|
||||
entrance = mEntrance,
|
||||
path = mPath)
|
||||
}
|
||||
}
|
||||
index++
|
||||
}
|
||||
|
||||
private fun bindImage(url: String, width: Int, height: Int, isChangeRatio: Boolean) {
|
||||
val binding = ItemCommunityImageBinding.inflate(LayoutInflater.from(context), null, false)
|
||||
binding.root.tag = index
|
||||
addView(binding.root)
|
||||
binding.durationOrNumTv.visibility = View.GONE
|
||||
binding.videoPlay.visibility = View.GONE
|
||||
displayImage(binding, url, width.toFloat(), height.toFloat(), isChangeRatio)
|
||||
binding.root.setOnClickListener {
|
||||
debounceActionWithInterval(it.id, 1000) {
|
||||
if (mAnswerEntity == null) return@debounceActionWithInterval
|
||||
val position = if (mAnswerEntity?.type == "community_article") {
|
||||
binding.root.tag as Int
|
||||
} else {
|
||||
if (mAnswerEntity!!.getPassVideos().isNullOrEmpty()) binding.root.tag as Int else (binding.root.tag as Int) - 1
|
||||
}
|
||||
val intent = ImageViewerActivity.getIntent(context, mAnswerEntity!!.images as ArrayList<String>, position, binding.root,
|
||||
if (mAnswerEntity?.type == "community_article") mAnswerEntity else null, mEntrance)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
index++
|
||||
}
|
||||
|
||||
private fun displayImage(binding: ItemCommunityImageBinding, url: String, width: Float, height: Float, isChangeRatio: Boolean, isVideo: Boolean = false) {
|
||||
val params = binding.root.layoutParams as LayoutParams
|
||||
val hierarchy = binding.image.hierarchy
|
||||
binding.labelIcon.visibility = View.GONE
|
||||
if (width != 0f && height != 0f) {
|
||||
val picRatio = width / height
|
||||
if (isChangeRatio) {
|
||||
when {
|
||||
picRatio <= mMinRatio -> {
|
||||
params.height = (mFixdWidth / mMinRatio).toInt()
|
||||
ImageUtils.display(binding.image, url, false, TopCutProcess(mMinRatio))
|
||||
}
|
||||
picRatio >= mMaxRatio -> {
|
||||
params.height = (mFixdWidth / mMaxRatio).toInt()
|
||||
ImageUtils.display(binding.image, url, false)
|
||||
}
|
||||
else -> {
|
||||
params.height = (mFixdWidth / picRatio).toInt()
|
||||
ImageUtils.display(binding.image, url, false)
|
||||
}
|
||||
}
|
||||
params.width = mFixdWidth.toInt()
|
||||
} else {
|
||||
params.width = mDefaultWidth.toInt()
|
||||
params.height = mDefaultWidth.toInt()
|
||||
ImageUtils.display(binding.image, url, false)
|
||||
}
|
||||
//长图
|
||||
if (!isVideo && picRatio <= mLongPictureRatio) {
|
||||
binding.labelIcon.visibility = View.VISIBLE
|
||||
binding.labelIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_long_pic_label))
|
||||
}
|
||||
} else {
|
||||
params.width = mDefaultWidth.toInt()
|
||||
params.height = mDefaultWidth.toInt()
|
||||
ImageUtils.display(binding.image, url, false)
|
||||
}
|
||||
|
||||
if (url.endsWith(".gif")) {
|
||||
binding.labelIcon.visibility = View.VISIBLE
|
||||
binding.labelIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_gif_label))
|
||||
}
|
||||
|
||||
val mediaCount = if (mAnswerEntity?.type == "community_article") {
|
||||
mAnswerEntity?.images?.size ?: 0
|
||||
} else {
|
||||
(mAnswerEntity?.images?.size ?: 0) + (mAnswerEntity?.getPassVideos()?.size ?: 0)
|
||||
}
|
||||
if (!isVideo && index == 2 && mediaCount > 3) {
|
||||
binding.labelIcon.visibility = View.GONE
|
||||
binding.durationOrNumTv.visibility = View.VISIBLE
|
||||
binding.durationOrNumTv.text = "+${mAnswerEntity?.images?.size}"
|
||||
}
|
||||
|
||||
hierarchy.actualImageScaleType = ScalingUtils.ScaleType.CENTER_CROP
|
||||
if (index != 0) params.leftMargin = mItemSpace
|
||||
binding.root.layoutParams = params
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ package com.gh.common.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
@ -31,6 +32,7 @@ public class MarqueeView extends ViewFlipper {
|
||||
private int textSize = 14;
|
||||
private int textColor = 0xffffffff;
|
||||
private boolean useSingleLineText = false;
|
||||
private boolean isHtmlText = false;
|
||||
|
||||
public MarqueeView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@ -121,9 +123,13 @@ public class MarqueeView extends ViewFlipper {
|
||||
tv.setEllipsize(TextUtils.TruncateAt.END);
|
||||
}
|
||||
tv.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
|
||||
tv.setText(text);
|
||||
tv.setTextColor(textColor);
|
||||
tv.setTextSize(textSize);
|
||||
tv.setTextColor(textColor);
|
||||
if (isHtmlText) {
|
||||
tv.setText(Html.fromHtml(text));
|
||||
} else {
|
||||
tv.setText(text);
|
||||
}
|
||||
return tv;
|
||||
}
|
||||
|
||||
@ -133,6 +139,12 @@ public class MarqueeView extends ViewFlipper {
|
||||
start();
|
||||
}
|
||||
|
||||
public void startWithListForHtmlText(List<String> notices) {
|
||||
isHtmlText = true;
|
||||
setNotices(notices);
|
||||
start();
|
||||
}
|
||||
|
||||
public void enableSingleLineText() {
|
||||
useSingleLineText = true;
|
||||
}
|
||||
|
||||
@ -25,6 +25,9 @@ class ReserveDialog : BaseDialogFragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
val binding: DialogReserveBinding = DataBindingUtil.inflate(inflater, R.layout.dialog_reserve, container, false)
|
||||
|
||||
mReserveList = arguments?.getParcelableArrayList(RESERVE_LIST) ?: arrayListOf()
|
||||
|
||||
binding.title.text = resources.getString(R.string.dialog_reserve_title, mReserveList.size).fromHtml()
|
||||
binding.more.visibility = if (mReserveList.size > 4) {
|
||||
View.VISIBLE
|
||||
@ -74,8 +77,13 @@ class ReserveDialog : BaseDialogFragment() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val RESERVE_LIST = "reserve_list"
|
||||
|
||||
@JvmStatic
|
||||
fun getInstance(reserveList: List<SimpleGameEntity>) = ReserveDialog().apply { mReserveList = reserveList }
|
||||
fun getInstance(reserveList: List<SimpleGameEntity>) = ReserveDialog().apply {
|
||||
arguments = Bundle()
|
||||
arguments?.putParcelableArrayList(RESERVE_LIST, ArrayList(reserveList))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -23,30 +23,31 @@ import androidx.viewpager.widget.ViewPager;
|
||||
*/
|
||||
|
||||
public class TabIndicatorView extends View implements ViewPager.OnPageChangeListener {
|
||||
|
||||
|
||||
private TabLayout mTabLayout;
|
||||
|
||||
|
||||
private int mIndicatorSpace;
|
||||
|
||||
|
||||
private int mIndicatorHeight;
|
||||
|
||||
|
||||
private int mIndicatorWidth;
|
||||
|
||||
|
||||
private int mIndicatorColor = 0;
|
||||
|
||||
|
||||
private GradientDrawable mGradientDrawable;
|
||||
|
||||
private Drawable mCustomDrawable;
|
||||
|
||||
public TabIndicatorView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
|
||||
public TabIndicatorView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
|
||||
public TabIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabIndicatorView);
|
||||
if (a.hasValue(R.styleable.TabIndicatorView_indicatorColor)) {
|
||||
mIndicatorColor = a.getColor(R.styleable.TabIndicatorView_indicatorColor, 0);
|
||||
@ -55,45 +56,48 @@ public class TabIndicatorView extends View implements ViewPager.OnPageChangeList
|
||||
mGradientDrawable.setColor(mIndicatorColor);
|
||||
mGradientDrawable.setCornerRadius(Integer.MAX_VALUE);
|
||||
}
|
||||
if (a.hasValue(R.styleable.TabIndicatorView_indicatorDrawable)) {
|
||||
mCustomDrawable = a.getDrawable(R.styleable.TabIndicatorView_indicatorDrawable);
|
||||
}
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
mIndicatorHeight = MeasureSpec.getSize(heightMeasureSpec);
|
||||
}
|
||||
|
||||
|
||||
public void setupWithTabLayout(final TabLayout tableLayout) {
|
||||
mTabLayout = tableLayout;
|
||||
|
||||
|
||||
tableLayout.setSelectedTabIndicatorColor(Color.TRANSPARENT);
|
||||
tableLayout.getViewTreeObserver().addOnScrollChangedListener(() -> {
|
||||
if (mTabLayout.getScrollX() != getScrollX())
|
||||
scrollTo(mTabLayout.getScrollX(), mTabLayout.getScrollY());
|
||||
});
|
||||
|
||||
|
||||
ViewCompat.setElevation(this, ViewCompat.getElevation(mTabLayout));
|
||||
|
||||
|
||||
//清除Tab background
|
||||
for (int tab = 0; tab < tableLayout.getTabCount(); tab++) {
|
||||
View tabView = getTabViewByPosition(tab);
|
||||
if (tabView != null) tabView.setBackgroundResource(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setupWithViewPager(ViewPager viewPager) {
|
||||
viewPager.addOnPageChangeListener(this);
|
||||
}
|
||||
|
||||
|
||||
public void setIndicatorWidth(int width) {
|
||||
if (width > 0) this.mIndicatorWidth = DisplayUtils.dip2px(getContext(), width);
|
||||
}
|
||||
|
||||
|
||||
public void setIndicatorSpace(int space) {
|
||||
this.mIndicatorSpace = DisplayUtils.dip2px(getContext(), space);
|
||||
}
|
||||
|
||||
|
||||
private int getIndicatorSpace() {
|
||||
if (mIndicatorSpace != 0) return mIndicatorSpace;
|
||||
if (mIndicatorWidth != 0) {
|
||||
@ -102,13 +106,15 @@ public class TabIndicatorView extends View implements ViewPager.OnPageChangeList
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
Drawable drawable;
|
||||
if (mGradientDrawable != null) {
|
||||
if (mCustomDrawable != null) {
|
||||
drawable = mCustomDrawable;
|
||||
} else if (mGradientDrawable != null) {
|
||||
drawable = mGradientDrawable;
|
||||
} else {
|
||||
drawable = getResources().getDrawable(R.drawable.ask_tab_indicator_bg); // 固定Indicator背景 有需要可以自行更改
|
||||
@ -116,77 +122,77 @@ public class TabIndicatorView extends View implements ViewPager.OnPageChangeList
|
||||
drawable.setBounds(l, t, r, b);
|
||||
drawable.draw(canvas);
|
||||
}
|
||||
|
||||
|
||||
int l;
|
||||
int t;
|
||||
int r;
|
||||
int b;
|
||||
|
||||
|
||||
public void generatePath(int position, float positionOffset) {
|
||||
RectF range = new RectF();
|
||||
View tabView = getTabViewByPosition(position);
|
||||
|
||||
|
||||
if (tabView == null) return;
|
||||
|
||||
|
||||
int left, top, right, bottom;
|
||||
left = top = right = bottom = 0;
|
||||
|
||||
|
||||
if (positionOffset > 0.f && position < mTabLayout.getTabCount() - 1) {
|
||||
View nextTabView = getTabViewByPosition(position + 1);
|
||||
if (nextTabView != null) {
|
||||
left += (int) (nextTabView.getLeft() * positionOffset + tabView.getLeft() * (1.f - positionOffset));
|
||||
right += (int) (nextTabView.getRight() * positionOffset + tabView.getRight() * (1.f - positionOffset));
|
||||
}
|
||||
|
||||
|
||||
left += getIndicatorSpace();
|
||||
right -= getIndicatorSpace();
|
||||
top = tabView.getTop() + getPaddingTop();
|
||||
bottom = tabView.getBottom() - getPaddingBottom();
|
||||
range.set(left, top, right, bottom);
|
||||
} else {
|
||||
|
||||
|
||||
left = tabView.getLeft() + getIndicatorSpace();
|
||||
right = tabView.getRight() - getIndicatorSpace();
|
||||
top = tabView.getTop() + getPaddingTop();
|
||||
bottom = tabView.getBottom() - getPaddingBottom();
|
||||
range.set(left, top, right, bottom);
|
||||
|
||||
|
||||
if (range.isEmpty()) return;
|
||||
}
|
||||
r = right;
|
||||
l = left;
|
||||
t = top;
|
||||
b = top + mIndicatorHeight;
|
||||
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
private View getTabViewByPosition(int position) {
|
||||
if (mTabLayout != null && mTabLayout.getTabCount() > 0) {
|
||||
ViewGroup tabStrip = (ViewGroup) mTabLayout.getChildAt(0);
|
||||
return tabStrip != null ? tabStrip.getChildAt(position) : null;
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
generatePath(position, positionOffset);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
if (mTabLayout.getSelectedTabPosition() != position) {
|
||||
TabLayout.Tab tab = mTabLayout.getTabAt(position);
|
||||
if (tab != null) tab.select();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -15,6 +15,7 @@ import android.os.Message;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.InflateException;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.ConsoleMessage;
|
||||
@ -34,6 +35,7 @@ import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
@ -284,6 +286,12 @@ public class DWebView extends WebView {
|
||||
// add dsbridge tag in lower android version
|
||||
settings.setUserAgentString(settings.getUserAgentString() + " _dsbridge");
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT < 19) {
|
||||
removeJavascriptInterface("searchBoxJavaBridge_");
|
||||
removeJavascriptInterface("accessibility");
|
||||
removeJavascriptInterface("accessibilityTraversal");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -414,7 +422,7 @@ public class DWebView extends WebView {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
super.loadUrl("javascript:" + script);
|
||||
} catch (Exception ignored){
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -716,6 +724,8 @@ public class DWebView extends WebView {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Activity activity = (AppCompatActivity) getContext();
|
||||
if (activity.isFinishing()) return true;
|
||||
Dialog alertDialog = new AlertDialog.Builder(getContext()).
|
||||
setMessage(message).
|
||||
setCancelable(false).
|
||||
@ -742,6 +752,8 @@ public class DWebView extends WebView {
|
||||
if (webChromeClient != null && webChromeClient.onJsConfirm(view, url, message, result)) {
|
||||
return true;
|
||||
} else {
|
||||
Activity activity = (AppCompatActivity) getContext();
|
||||
if (activity.isFinishing()) return true;
|
||||
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
@ -784,6 +796,8 @@ public class DWebView extends WebView {
|
||||
if (webChromeClient != null && webChromeClient.onJsPrompt(view, url, message, defaultValue, result)) {
|
||||
return true;
|
||||
} else {
|
||||
Activity activity = (AppCompatActivity) getContext();
|
||||
if (activity.isFinishing()) return true;
|
||||
final EditText editText = new EditText(getContext());
|
||||
editText.setText(defaultValue);
|
||||
if (defaultValue != null) {
|
||||
@ -1023,4 +1037,16 @@ public class DWebView extends WebView {
|
||||
mainHandler.post(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOverScrollMode(int mode) {
|
||||
try {
|
||||
super.setOverScrollMode(mode);
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof InflateException) {
|
||||
e.printStackTrace();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,7 +163,13 @@ public class PagerLayoutManager extends LinearLayoutManager {
|
||||
return 0;
|
||||
}
|
||||
this.mDrift = dy;
|
||||
return super.scrollVerticallyBy(dy, recycler, state);
|
||||
//fix for `java.lang.IndexOutOfBoundsException: Inconsistency detected.`
|
||||
try {
|
||||
return super.scrollVerticallyBy(dy, recycler, state);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -18,7 +18,7 @@ import java.util.*
|
||||
* 目前检验是否已解压的根据是存在相同文件名且大小一致(暂时想不到校验MD5值的方法)
|
||||
*
|
||||
* obb文件直接解压至根目录即可,无需操作文件
|
||||
* apk文件这解压的gh-download文件夹中
|
||||
* apk文件这解压的gh-files文件夹中
|
||||
*/
|
||||
object XapkInstaller : IXapkUnzipListener {
|
||||
private const val XAPK_PACKAGE_PATH_TAG = "xapk_package_path"
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
package com.gh.download
|
||||
|
||||
import android.content.pm.PackageManager
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.common.exposure.meta.MetaUtil.getMeta
|
||||
import com.gh.common.loghub.LoghubUtils
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.DeviceUtils
|
||||
import com.gh.common.util.getExtension
|
||||
import com.gh.common.util.isSimulatorGame
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.halo.assistant.HaloApp
|
||||
@ -339,13 +340,13 @@ object DownloadDataHelper {
|
||||
val meta = getMeta()
|
||||
// meta
|
||||
val metaObject = JSONObject()
|
||||
metaObject.put("android_id", meta.android_id)
|
||||
metaObject.put("dia", MetaUtil.getBase64EncodedAndroidId())
|
||||
metaObject.put("android_sdk", meta.android_sdk)
|
||||
metaObject.put("android_version", meta.android_version)
|
||||
metaObject.put("appVersion", meta.appVersion)
|
||||
metaObject.put("channel", meta.channel)
|
||||
metaObject.put("gid", meta.gid)
|
||||
metaObject.put("imei", meta.imei)
|
||||
metaObject.put("jnfj", MetaUtil.getBase64EncodedIMEI())
|
||||
metaObject.put("mac", meta.mac)
|
||||
metaObject.put("manufacturer", meta.manufacturer)
|
||||
metaObject.put("model", meta.model)
|
||||
|
||||
@ -52,6 +52,7 @@ import com.lightgame.download.DownloadService;
|
||||
import com.lightgame.download.DownloadStatus;
|
||||
import com.lightgame.download.DownloadStatusListener;
|
||||
import com.lightgame.download.DownloadStatusManager;
|
||||
import com.lightgame.download.DownloadTask;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.download.HttpDnsManager;
|
||||
import com.lightgame.utils.Utils;
|
||||
@ -277,7 +278,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT, gameEntity.getIconSubscript());
|
||||
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR_GAME, apkEntity.getFormat());
|
||||
HaloApp.put(GameEntity.class.getSimpleName(), gameEntity);
|
||||
HaloApp.put(downloadEntity.getPath(), gameEntity);
|
||||
}
|
||||
int installed = 0;
|
||||
for (ApkEntity apk : gameEntity.getApk()) {
|
||||
@ -485,6 +486,8 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
* @return null表示下载列表中不存在该任务,否则返回下载任务
|
||||
*/
|
||||
public DownloadEntity getDownloadEntityByPackageName(String packageName) {
|
||||
if (mDownloadDao == null) return null;
|
||||
|
||||
for (DownloadEntity downloadEntity : mDownloadDao.getAll()) {
|
||||
if (packageName.equals(downloadEntity.getPackageName())) {
|
||||
return downloadEntity;
|
||||
@ -543,7 +546,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
}
|
||||
|
||||
public List<DownloadEntity> getAllSimulatorDownloadEntity() {
|
||||
List<DownloadEntity> downloadEntityList = mDownloadDao.getAll();
|
||||
List<DownloadEntity> downloadEntityList = getAllDownloadEntity();
|
||||
ArrayList<DownloadEntity> filteredDownloadEntityList = new ArrayList<>();
|
||||
for (DownloadEntity downloadEntity : downloadEntityList) {
|
||||
if (ExtensionsKt.isSimulatorGame(downloadEntity) && downloadEntity.getStatus() == DownloadStatus.done) {
|
||||
@ -560,7 +563,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
if (CommonDebug.IS_DEBUG) {
|
||||
CommonDebug.logMethodName(this);
|
||||
}
|
||||
List<DownloadEntity> all = mDownloadDao.getAll();
|
||||
List<DownloadEntity> all = getAllDownloadEntity();
|
||||
return filterSilentDownloadTask(all);
|
||||
}
|
||||
|
||||
@ -630,7 +633,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
FileUtils.deleteFile(entry.getPath());
|
||||
}
|
||||
mDownloadDao.delete(url);
|
||||
Utils.log(DownloadManager.class.getSimpleName(), "cancel==>file and record were deleted!");
|
||||
Utils.log(DownloadManager.class.getSimpleName(), "cancel==>record were deleted!");
|
||||
}
|
||||
if (entry != null) {
|
||||
if (automatic) {
|
||||
@ -639,8 +642,26 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
entry.getMeta().put(DownloadDataHelper.DOWNLOAD_CANCEL_WAY, DownloadDataHelper.DOWNLOAD_CANCEL_MANUAL);
|
||||
}
|
||||
entry.setStatus(DownloadStatus.cancel);
|
||||
startDownloadService(entry, DownloadStatus.cancel);
|
||||
Utils.log(DownloadManager.class.getSimpleName(), "cancel");
|
||||
|
||||
// startDownloadService(entry, DownloadStatus.cancel);
|
||||
|
||||
// 将原来安装完成后在 downloadService 完成的功能放到这里,尝试避免因为 ANR 造成闪退
|
||||
AppExecutor.getUiExecutor().executeWithDelay(() -> {
|
||||
mDownloadDao.removeErrorMessage(entry.getUrl());
|
||||
|
||||
DownloadTask task = DataChanger.INSTANCE.getDownloadingTasks().get(entry.getUrl());
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
// 改任务队列的状态
|
||||
DataChanger.INSTANCE.getDownloadingTasks().remove(entry.getUrl());
|
||||
DataChanger.INSTANCE.notifyDataChanged(entry);
|
||||
}
|
||||
DataChanger.INSTANCE.getDownloadEntries().remove(entry.getUrl());
|
||||
DataChanger.INSTANCE.notifyDataChanged(entry);
|
||||
DownloadStatusManager.getInstance().onTaskCancelled(entry);
|
||||
|
||||
Utils.log(DownloadManager.class.getSimpleName(), "cancel");
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -153,14 +153,6 @@ object PackageObserver {
|
||||
e.printStackTrace()
|
||||
}
|
||||
LoghubUtils.log(wrapperObject, "halo-api-device-installed", true)
|
||||
val requestBody = RequestBody.create(MediaType.parse("application/json"),
|
||||
packageObject.toString())
|
||||
// 更新已安装游戏
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.postNewlyInstalledApp(HaloApp.getInstance().gid, requestBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(EmptyResponse())
|
||||
if (!TextUtils.isEmpty(gameId) && UserManager.getInstance().isLoggedIn) {
|
||||
val jsonObject = JSONObject()
|
||||
try {
|
||||
|
||||
@ -28,19 +28,22 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
|
||||
import butterknife.BindView
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.DefaultOnImageEventListener
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.imagepipeline.core.ImagePipeline
|
||||
import com.facebook.imagepipeline.request.ImageRequest
|
||||
import com.gh.base.BaseActivity
|
||||
import com.gh.common.Base64ImageHolder.image
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.runOnIoThread
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.ImageUtils.getTransformLimitUrl
|
||||
import com.gh.common.view.DraggableBigImageView
|
||||
import com.gh.common.view.Gh_RelativeLayout
|
||||
import com.gh.common.view.Gh_ViewPager
|
||||
import com.gh.gamecenter.entity.CommunityEntity
|
||||
import com.gh.gamecenter.entity.ImageInfoEntity
|
||||
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
|
||||
import com.gh.gamecenter.qa.entity.AnswerEntity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.github.piasy.biv.view.BigImageView
|
||||
@ -50,6 +53,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.io.*
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
/**
|
||||
* 查看游戏截图页面
|
||||
@ -78,6 +82,9 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
@BindView(R.id.btn_save_pic)
|
||||
lateinit var mSavePicBtn: View
|
||||
|
||||
@BindView(R.id.btn_article_detail)
|
||||
lateinit var mArticleDetailBtn: View
|
||||
|
||||
private var adapter: ViewImageAdapter? = null
|
||||
private var mImagePipeline: ImagePipeline? = null
|
||||
private var mShowBase64Image = false
|
||||
@ -90,6 +97,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
private var mInitialPosition = 0
|
||||
private var mUseEnterAndExitAnimation = false
|
||||
private var mShowSaveBtn = false
|
||||
private var mAnswerEntity: AnswerEntity? = null
|
||||
|
||||
private var mLimitWidth = 0
|
||||
private var mOriginLeft = 0
|
||||
@ -128,14 +136,16 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
}
|
||||
mShowSaveBtn = it.getBoolean(KEY_SHOW_SAVE)
|
||||
mUseEnterAndExitAnimation = it.getBoolean(KEY_USE_ENTER_AND_EXIT_ANIMATION)
|
||||
mAnswerEntity = it.getParcelable(AnswerEntity::class.java.name)
|
||||
}
|
||||
mSavePicBtn.visibleIf(mShowSaveBtn)
|
||||
mArticleDetailBtn.visibleIf(mAnswerEntity != null)
|
||||
mIndicatorMask.goneIf(mUrlList?.size == 1)
|
||||
mIndicatorTv.text = String.format("%d/%d", mInitialPosition + 1, mUrlList!!.size)
|
||||
|
||||
// init slide
|
||||
val outMetrics = DisplayMetrics()
|
||||
windowManager.defaultDisplay.getMetrics(outMetrics)
|
||||
windowManager?.defaultDisplay?.getMetrics(outMetrics)
|
||||
val widthPixels = outMetrics.widthPixels
|
||||
mLimitWidth = if (NetworkUtils.isWifiOr4GConnected(this)) {
|
||||
widthPixels * 2
|
||||
@ -182,7 +192,14 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
adapter?.saveImageToFile(this, mFinalUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mArticleDetailBtn.setOnClickListener {
|
||||
val intent = ArticleDetailActivity.getIntent(this, CommunityEntity(mAnswerEntity?.communityId
|
||||
?: "", mAnswerEntity?.communityName ?: ""), mAnswerEntity?.id
|
||||
?: "", mEntrance, "")
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
|
||||
initEnterAnimation()
|
||||
@ -197,7 +214,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (mShowBase64Image) {
|
||||
mUrlList!!.clear()
|
||||
mUrlList?.clear()
|
||||
image = ""
|
||||
}
|
||||
mViewPager.onDestroy() // 注销EventBus
|
||||
@ -266,7 +283,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
}
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
var ghRelativeLayout: Gh_RelativeLayout?
|
||||
/*var ghRelativeLayout: Gh_RelativeLayout?
|
||||
for (i in 0 until mViewPager.childCount) {
|
||||
if (mViewPager.getChildAt(i).tag != null) {
|
||||
ghRelativeLayout = mViewPager.getChildAt(i) as? Gh_RelativeLayout
|
||||
@ -277,7 +294,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
val ssiv = imageView.ssiv
|
||||
ssiv?.resetScaleAndCenter()
|
||||
}
|
||||
}
|
||||
}*/
|
||||
mIndicatorTv.text = String.format("%d/%d", position + 1, mUrlList!!.size)
|
||||
}
|
||||
|
||||
@ -337,11 +354,13 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
})
|
||||
}
|
||||
|
||||
private fun loadImage(originalUrl: String, decoratedUrl: String?, imageView: BigImageView) {
|
||||
if (TextUtils.isEmpty(originalUrl)) return
|
||||
if (originalUrl.startsWith("data:image/png;base64")) {
|
||||
private fun loadImage(thumbnailUrl: String,
|
||||
compressedUrl: String?,
|
||||
imageView: BigImageView) {
|
||||
if (TextUtils.isEmpty(thumbnailUrl)) return
|
||||
if (thumbnailUrl.startsWith("data:image/png;base64")) {
|
||||
runOnIoThread {
|
||||
val base64String = originalUrl.replace("data:image/png;base64", "")
|
||||
val base64String = thumbnailUrl.replace("data:image/png;base64", "")
|
||||
try {
|
||||
val imageFile = File(cacheDir.absolutePath + File.separator + System.currentTimeMillis() + ".png")
|
||||
val decodedString = Base64.decode(base64String, Base64.DEFAULT)
|
||||
@ -361,7 +380,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
// 添加GIF支持
|
||||
imageView.setImageViewFactory(FrescoImageViewFactory())
|
||||
imageView.setThumbnailScaleType(ImageView.ScaleType.FIT_CENTER)
|
||||
imageView.showImage(Uri.parse(originalUrl), Uri.parse(decoratedUrl))
|
||||
imageView.showImage(Uri.parse(thumbnailUrl), Uri.parse(compressedUrl))
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,7 +450,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
duration = ANIMATION_DURATION
|
||||
doOnStart { mIndicatorMask.visibility = View.GONE }
|
||||
doOnEnd {
|
||||
if (mUrlList?.size != 1) {
|
||||
if (mUrlList?.size != 1 || mAnswerEntity != null) {
|
||||
mIndicatorMask.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
@ -441,7 +460,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
private fun performExitAnimation(view: DraggableBigImageView, scale: Float, fadeOnly: Boolean) {
|
||||
val finalScale = mOriginWidth / mTargetWidth
|
||||
val finalTranslationX = mOriginLeft - (1 - finalScale) * mTargetWidth / 2
|
||||
val finalTranslationY = mOriginTop - ((1 - finalScale) * mTargetHeight + (mTargetHeight * finalScale - mOriginHeight)) / 2
|
||||
val finalTranslationY = mOriginTop - ((1 - finalScale) * mTargetHeight + (mTargetHeight * finalScale - mOriginHeight)) / 2
|
||||
|
||||
val animatorSet = AnimatorSet()
|
||||
|
||||
@ -485,9 +504,20 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||
val originalUrl = mUrlList!![position]
|
||||
var decoratedUrl: String? = originalUrl
|
||||
val imageRequest = ImageRequest.fromUri(originalUrl)
|
||||
val rawUrl = mUrlList!![position]
|
||||
|
||||
var thumbnailImageUrl = if (!mShowBase64Image) {
|
||||
ImageUtils.getCachedUrl(rawUrl)
|
||||
} else {
|
||||
rawUrl
|
||||
}
|
||||
var compressedStandardImageUrl: String? = if (!mShowBase64Image && rawUrl.contains("ghzs")) {
|
||||
// 用 oss.jpeg 加上 limit 以后会出现双指放大的情况
|
||||
rawUrl + Config.getSettings()?.image?.oss?.gif
|
||||
} else {
|
||||
rawUrl
|
||||
}
|
||||
val imageRequest = ImageRequest.fromUri(thumbnailImageUrl)
|
||||
val isInMemoryCache = mImagePipeline!!.isInBitmapMemoryCache(imageRequest)
|
||||
val isInDiskCache = imageRequest != null && mImagePipeline!!.isInDiskCacheSync(imageRequest)
|
||||
val view = View.inflate(container.context, R.layout.viewimage_normal_item, null) as Gh_RelativeLayout
|
||||
@ -507,16 +537,21 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
|
||||
override fun onRestore(draggableBigImageView: DraggableBigImageView, fraction: Float) {
|
||||
mBackgroundView.alpha = 1F
|
||||
mIndicatorMask.goneIf(mUrlList?.size == 1)
|
||||
// mIndicatorMask.goneIf(mUrlList?.size == 1)
|
||||
if (mUrlList?.size != 1 || mAnswerEntity != null) {
|
||||
mIndicatorMask.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
})
|
||||
// 弱网环境加载低质量图片
|
||||
if (!isInMemoryCache
|
||||
&& !isInDiskCache
|
||||
&& !NetworkUtils.isWifiOr4GConnected(this@ImageViewerActivity)
|
||||
&& !originalUrl.contains(".gif")) {
|
||||
decoratedUrl = getTransformLimitUrl(originalUrl, mLimitWidth, applicationContext)
|
||||
&& !thumbnailImageUrl.contains(".gif")) {
|
||||
compressedStandardImageUrl = getTransformLimitUrl(thumbnailImageUrl, mLimitWidth, applicationContext)
|
||||
thumbnailImageUrl = compressedStandardImageUrl ?: ""
|
||||
}
|
||||
val finalUrl = decoratedUrl
|
||||
val finalUrl = compressedStandardImageUrl
|
||||
mFinalUrl = finalUrl ?: ""
|
||||
|
||||
imageView.setImageLoaderCallback(object : SimpleImageLoader() {
|
||||
@ -530,16 +565,16 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
val ssiv = imageView.ssiv
|
||||
if (ssiv != null) {
|
||||
ssiv.maxScale = 10f // 这个缩放倍数最好很具宽高自动调节
|
||||
ssiv.setOnImageEventListener(object : DefaultOnImageEventListener() {
|
||||
override fun onReady() {
|
||||
ssiv.resetScaleAndCenter()
|
||||
}
|
||||
})
|
||||
// ssiv.setOnImageEventListener(object : DefaultOnImageEventListener() {
|
||||
// override fun onReady() {
|
||||
// ssiv.resetScaleAndCenter()
|
||||
// }
|
||||
// })
|
||||
ssiv.setOnClickListener { finishWithAnimation(mInitialPosition != mViewPager.currentItem) }
|
||||
}
|
||||
}
|
||||
})
|
||||
loadImage(originalUrl, decoratedUrl, imageView)
|
||||
loadImage(thumbnailImageUrl, compressedStandardImageUrl, imageView)
|
||||
|
||||
//长按
|
||||
imageView.setOnLongClickListener {
|
||||
@ -670,15 +705,21 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
return getIntent(context, list, position, originalView, entrance, false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getIntent(context: Context, list: ArrayList<String>, position: Int = 0, originalView: View? = null, answerEntity: AnswerEntity? = null, entrance: String?): Intent {
|
||||
return getIntent(context, list, position, originalView, entrance, false, answerEntity)
|
||||
}
|
||||
|
||||
/**
|
||||
* 传入 view 代表使用渐入渐出动画
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getIntent(context: Context, list: ArrayList<String>, position: Int = 0, originalView: View? = null, entrance: String?, isShowSaveBtn: Boolean): Intent {
|
||||
fun getIntent(context: Context, list: ArrayList<String>, position: Int = 0, originalView: View? = null, entrance: String?, isShowSaveBtn: Boolean, answerEntity: AnswerEntity? = null): Intent {
|
||||
val intent = Intent(context, ImageViewerActivity::class.java)
|
||||
intent.putExtra(KEY_URL_LIST, list)
|
||||
intent.putExtra(KEY_CURRENT, position)
|
||||
intent.putExtra(KEY_SHOW_SAVE, isShowSaveBtn)
|
||||
intent.putExtra(AnswerEntity::class.java.name, answerEntity)
|
||||
intent.putExtra(EntranceUtils.KEY_ENTRANCE, entrance)
|
||||
|
||||
val location = IntArray(2)
|
||||
|
||||
@ -2,7 +2,6 @@ package com.gh.gamecenter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
@ -19,7 +18,6 @@ import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RestrictTo;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import com.gh.base.AppUncaughtHandler;
|
||||
@ -31,13 +29,10 @@ import com.gh.common.avoidcallback.AvoidOnResultManager;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.constant.Constants;
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
import com.gh.common.loghub.LoghubUtils;
|
||||
import com.gh.common.repository.ReservationRepository;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.common.util.ActivationHelper;
|
||||
import com.gh.common.util.ClassUtils;
|
||||
import com.gh.common.util.ConcernUtils;
|
||||
import com.gh.common.util.DataCollectionUtils;
|
||||
import com.gh.common.util.DataUtils;
|
||||
import com.gh.common.util.DeviceTokenUtils;
|
||||
import com.gh.common.util.DeviceUtils;
|
||||
@ -57,18 +52,14 @@ import com.gh.common.util.PackageUtils;
|
||||
import com.gh.common.util.PlatformUtils;
|
||||
import com.gh.common.util.SPUtils;
|
||||
import com.gh.common.util.ShareUtils;
|
||||
import com.gh.common.util.ThirdPartyPackageHelper;
|
||||
import com.gh.common.util.ToastUtils;
|
||||
import com.gh.common.util.UrlFilterUtils;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.download.DownloadFragment;
|
||||
import com.gh.gamecenter.entity.CommunityEntity;
|
||||
import com.gh.gamecenter.entity.GameDigestEntity;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.InnerMetaInfoEntity;
|
||||
import com.gh.gamecenter.entity.NotificationUgc;
|
||||
import com.gh.gamecenter.eventbus.EBNetworkState;
|
||||
import com.gh.gamecenter.eventbus.EBPackage;
|
||||
import com.gh.gamecenter.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.eventbus.EBSkip;
|
||||
import com.gh.gamecenter.fragment.MainWrapperFragment;
|
||||
@ -77,11 +68,9 @@ import com.gh.gamecenter.manager.DataCollectionManager;
|
||||
import com.gh.gamecenter.manager.UpdateManager;
|
||||
import com.gh.gamecenter.manager.UserManager;
|
||||
import com.gh.gamecenter.normal.NormalFragment;
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository;
|
||||
import com.gh.gamecenter.packagehelper.PackageViewModel;
|
||||
import com.gh.gamecenter.qa.CommunityFragment;
|
||||
import com.gh.gamecenter.retrofit.BiResponse;
|
||||
import com.gh.gamecenter.retrofit.EmptyResponse;
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.gh.gamecenter.suggest.SuggestSelectFragment;
|
||||
@ -90,7 +79,6 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.halo.assistant.fragment.SettingsFragment;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.download.DownloadStatus;
|
||||
import com.lightgame.download.FileUtils;
|
||||
@ -101,7 +89,6 @@ import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@ -111,7 +98,6 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
@ -183,8 +169,11 @@ public class MainActivity extends BaseActivity {
|
||||
if (!this.isFinishing()) {
|
||||
LogUtils.uploadDevice(lunchType);
|
||||
ActivationHelper.sendActivationInfo();
|
||||
// 第一次打开App删除模拟器游戏记录
|
||||
SimulatorGameManager.deleteAllSimulatorGame();
|
||||
// 第一次打开App删除模拟器游戏记录(不包括更新版本)
|
||||
if (HaloApp.getInstance().isBrandNewInstall) {
|
||||
SimulatorGameManager.deleteAllSimulatorGame();
|
||||
|
||||
}
|
||||
}
|
||||
}, 2000L);
|
||||
getPluginUpdate();
|
||||
|
||||
@ -111,8 +111,8 @@ public abstract class NormalActivity extends ToolBarActivity {
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mTargetFragment.isAdded()
|
||||
&& mTargetFragment instanceof NormalFragment
|
||||
if (mTargetFragment instanceof NormalFragment
|
||||
&& mTargetFragment.isAdded()
|
||||
&& !((NormalFragment) mTargetFragment).onBackPressed()) {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@ -389,7 +389,12 @@ public class SkipActivity extends BaseActivity {
|
||||
}
|
||||
} else if ("market".equals(uri.getScheme())) {
|
||||
String host = uri.getHost();
|
||||
String id = uri.getQueryParameter("id");
|
||||
String id = "";
|
||||
try {
|
||||
id = uri.getQueryParameter("id");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (host != null) {
|
||||
if ("details".equals(host)) {
|
||||
bundle = new Bundle();
|
||||
|
||||
@ -287,8 +287,6 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
private void launchMainActivity() {
|
||||
HaloApp.getInstance().postInit();
|
||||
|
||||
getUniqueId();
|
||||
|
||||
prefetchData();
|
||||
|
||||
uploadTeaAndGdtData();
|
||||
@ -300,7 +298,7 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
finish();
|
||||
}
|
||||
|
||||
private void uploadTeaAndGdtData(){
|
||||
private void uploadTeaAndGdtData() {
|
||||
// 在可能获取了相关权限后才初始化SDK/发送激活数据
|
||||
// TeaHelper.init(getApplication(), HaloApp.getInstance().getChannel());
|
||||
try {
|
||||
@ -422,25 +420,25 @@ public class SplashScreenActivity extends BaseActivity {
|
||||
// 检查下载文件夹下是否有旧版本的光环助手的包,有则删除
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
private void deleteOutdatedUpdatePackage() {
|
||||
File folder = new File(FileUtils.getDownloadDir(this) + File.separator);
|
||||
if (folder.isDirectory()) {
|
||||
for (File file : folder.listFiles()) {
|
||||
if (!file.isDirectory() && file.getName().startsWith("光环助手V")) {
|
||||
String name = file.getName();
|
||||
int index = name.indexOf("_");
|
||||
if (index != -1) {
|
||||
try {
|
||||
try {
|
||||
File folder = new File(FileUtils.getDownloadDir(this) + File.separator);
|
||||
if (folder.isDirectory()) {
|
||||
for (File file : folder.listFiles()) {
|
||||
if (!file.isDirectory() && file.getName().startsWith("光环助手V")) {
|
||||
String name = file.getName();
|
||||
int index = name.indexOf("_");
|
||||
if (index != -1) {
|
||||
String versionString = name.substring(name.indexOf("V") + 1, index);
|
||||
Version currentVersion = new Version(PackageUtils.getVersionName());
|
||||
if (currentVersion.isHigherThan(versionString) || currentVersion.isEqual(versionString)) {
|
||||
file.delete();
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -355,6 +355,8 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Bundle extras = getIntent().getExtras();
|
||||
if (extras == null) return;
|
||||
|
||||
Object suggestType = extras.get(EntranceUtils.KEY_SUGGESTTYPE);
|
||||
if (suggestType instanceof SuggestType) {
|
||||
mSuggestType = (SuggestType) suggestType;
|
||||
@ -1042,7 +1044,7 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
|
||||
params.put("sdk", String.valueOf(android.os.Build.VERSION.SDK_INT));
|
||||
params.put("version", android.os.Build.VERSION.RELEASE);
|
||||
params.put("source", getString(R.string.app_name));
|
||||
params.put("imei", MetaUtil.getIMEI());
|
||||
params.put("jnfj", MetaUtil.getBase64EncodedIMEI());
|
||||
params.put("manufacturer", Build.MANUFACTURER);
|
||||
params.put("rom", RomIdentifier.getRom().name() + " " + RomIdentifier.getRom().getVersionName());
|
||||
|
||||
@ -1072,14 +1074,14 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
|
||||
params.put("sdk", String.valueOf(android.os.Build.VERSION.SDK_INT));
|
||||
params.put("version", android.os.Build.VERSION.RELEASE);
|
||||
params.put("source", getString(R.string.app_name));
|
||||
params.put("imei", MetaUtil.getIMEI());
|
||||
params.put("jnfj", MetaUtil.getBase64EncodedIMEI());
|
||||
params.put("manufacturer", Build.MANUFACTURER);
|
||||
params.put("rom", RomIdentifier.getRom().name() + " " + RomIdentifier.getRom().getVersionName());
|
||||
params.put("link", mLinkEt.getText().toString());
|
||||
|
||||
if (fromRating) {
|
||||
params.put("suggestion_type", mSuggestType.getType() + "(评论)");
|
||||
} else if (!mDiagnosisResult.isEmpty()){
|
||||
} else if (!mDiagnosisResult.isEmpty()) {
|
||||
params.put("suggestion_type", "网络诊断");
|
||||
} else {
|
||||
params.put("suggestion_type", mSuggestType.getType());
|
||||
@ -1251,7 +1253,7 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
|
||||
public String readFromFile() {
|
||||
|
||||
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
||||
|
||||
if (getExternalFilesDir(null) == null) return "SD Card error";
|
||||
File file = new File(getExternalFilesDir(null).getPath() + "/log");
|
||||
if (file.isFile()) return "检测log文件夹是文件";
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.gh.common.util.BiCallback;
|
||||
import com.gh.common.util.EnergyTaskHelper;
|
||||
import com.gh.common.util.ImageUtils;
|
||||
import com.gh.common.util.LogUtils;
|
||||
import com.gh.common.util.ShareUtils;
|
||||
@ -66,6 +67,9 @@ public class WeiBoShareActivity extends Activity implements WbShareCallback {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Bundle extras = getIntent().getExtras();
|
||||
|
||||
if (extras == null) return;
|
||||
|
||||
mTitle = extras.getString(KET_TITLE);
|
||||
String shareIcon = extras.getString(KET_SHAREICON);
|
||||
mSummary = extras.getString(KET_SUMMARY);
|
||||
@ -77,7 +81,11 @@ public class WeiBoShareActivity extends Activity implements WbShareCallback {
|
||||
mWeiboShareAPI = new WbShareHandler(this);
|
||||
mWeiboShareAPI.registerApp();
|
||||
|
||||
loadIconAndShare(shareIcon);
|
||||
if (shareIcon != null) {
|
||||
loadIconAndShare(shareIcon);
|
||||
} else {
|
||||
onWbShareFail();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -151,6 +159,7 @@ public class WeiBoShareActivity extends Activity implements WbShareCallback {
|
||||
LogUtils.uploadShareResult(ShareUtils.shareType, ShareUtils.shareEntrance.getName(), "success",
|
||||
ShareUtils.shareEntity.getShareUrl(), ShareUtils.shareEntity.getShareTitle(), ShareUtils.shareEntity.getSummary(), ShareUtils.resourceId);
|
||||
EventBus.getDefault().post(new EBShare(ShareUtils.shareEntrance));
|
||||
EnergyTaskHelper.postEnergyTaskForShare(ShareUtils.shareEntrance.getName(), ShareUtils.resourceId, ShareUtils.shareEntity.getShareUrl());
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
@ -88,6 +88,7 @@ public class ImagePagerAdapter extends RecyclingPagerAdapter {
|
||||
GameEntity fakeGameEntity = new GameEntity();
|
||||
fakeGameEntity.setId(slideEntity.getLink());
|
||||
fakeGameEntity.setName(slideEntity.getText());
|
||||
fakeGameEntity.setSequence(index);
|
||||
|
||||
exposureEvent = ExposureEvent.createEvent(fakeGameEntity, mExposureSourceList, null, ExposureType.EXPOSURE);
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ import com.gh.common.util.DataUtils;
|
||||
import com.gh.common.util.DetailDownloadUtils;
|
||||
import com.gh.common.util.DialogUtils;
|
||||
import com.gh.common.util.DownloadDialogHelper;
|
||||
import com.gh.common.util.EnergyTaskHelper;
|
||||
import com.gh.common.util.LogUtils;
|
||||
import com.gh.common.util.MtaHelper;
|
||||
import com.gh.common.util.PackageInstaller;
|
||||
@ -105,7 +106,8 @@ public class DetailViewHolder {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// 这个 switch 纯粹是为了 MTA 统计用的
|
||||
// 这个 switch 纯粹是为了 MTA和上报光能任务 统计用的
|
||||
if (mViewHolder.mDownloadPb.getDownloadType() == null) return;
|
||||
switch (mViewHolder.mDownloadPb.getDownloadType()) {
|
||||
case DOWNLOADING_PLUGIN:
|
||||
MtaHelper.onEvent("游戏详情_新", "插件化中", mGameEntity.getName());
|
||||
@ -118,6 +120,7 @@ public class DetailViewHolder {
|
||||
break;
|
||||
case NORMAL:
|
||||
MtaHelper.onEvent("游戏详情_新", "下载", mGameEntity.getName());
|
||||
EnergyTaskHelper.postEnergyTask("download_game", mGameEntity.getId(), mGameEntity.getApk().get(0).getPackageName());
|
||||
break;
|
||||
case PLUGIN:
|
||||
MtaHelper.onEvent("游戏详情_新", "插件化", mGameEntity.getName());
|
||||
@ -131,6 +134,9 @@ public class DetailViewHolder {
|
||||
case RESERVABLE:
|
||||
MtaHelper.onEvent("游戏详情_新", "预约", mGameEntity.getName());
|
||||
break;
|
||||
case LAUNCH_OR_OPEN:
|
||||
EnergyTaskHelper.postEnergyTask("play_game", mGameEntity.getId(), mGameEntity.getApk().get(0).getPackageName());
|
||||
break;
|
||||
}
|
||||
// 由于部分状态不包含在 downloadType 里,所以还是需要手动获取下载按钮文字判断点击时的状态
|
||||
String downloadText = mViewHolder.mDownloadPb.getText();
|
||||
@ -292,10 +298,12 @@ public class DetailViewHolder {
|
||||
Utils.toast(mViewHolder.context, "正在加急更新版本,敬请后续留意");
|
||||
break;
|
||||
default:
|
||||
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(mViewHolder.context,
|
||||
mGameEntity.getApk().get(0).getUrl(),
|
||||
StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"));
|
||||
mViewHolder.context.startActivity(intent);
|
||||
if (!mGameEntity.getApk().isEmpty()) {
|
||||
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(mViewHolder.context,
|
||||
mGameEntity.getApk().get(0).getUrl(),
|
||||
StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"));
|
||||
mViewHolder.context.startActivity(intent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,10 +2,7 @@ package com.gh.gamecenter.amway
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.common.util.ErrorHelper
|
||||
import com.gh.common.util.LogUtils
|
||||
import com.gh.common.util.ToastUtils
|
||||
import com.gh.common.util.*
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.baselist.ListViewModel
|
||||
import com.gh.gamecenter.baselist.LoadStatus
|
||||
@ -209,6 +206,8 @@ class AmwayViewModel(application: Application) : ListViewModel<AmwayCommentEntit
|
||||
|
||||
Utils.toast(getApplication(), "点赞成功")
|
||||
updateAmwayCommentLikeCount(commentId, increaseCount = true, isLiked = true)
|
||||
|
||||
EnergyTaskHelper.postEnergyTask("vote_game_comment", commentId)
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
|
||||
@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import com.gh.common.util.ExtensionsKt;
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -46,6 +47,7 @@ public abstract class ListAdapter<DataType> extends BaseRecyclerAdapter {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO 复用线程
|
||||
new AsyncTask<Void, Void, DiffUtil.DiffResult>() {
|
||||
@Override
|
||||
protected DiffUtil.DiffResult doInBackground(Void... voids) {
|
||||
@ -65,8 +67,9 @@ public abstract class ListAdapter<DataType> extends BaseRecyclerAdapter {
|
||||
if (oldItemPosition >= mEntityList.size()) return false;
|
||||
if (newItemPosition >= updateData.size()) return false;
|
||||
|
||||
DataType oldItem = mEntityList.get(oldItemPosition);
|
||||
DataType newItem = updateData.get(newItemPosition);
|
||||
// TODO 看看有什么方式可以避免多线程访问 mEntityList (所有 ListAdapter 共用一个线程?)
|
||||
DataType oldItem = ExtensionsKt.safelyGetInRelease(mEntityList, oldItemPosition);
|
||||
DataType newItem = ExtensionsKt.safelyGetInRelease(updateData, newItemPosition);
|
||||
return ListAdapter.this.areItemsTheSame(oldItem, newItem);
|
||||
}
|
||||
|
||||
@ -75,8 +78,8 @@ public abstract class ListAdapter<DataType> extends BaseRecyclerAdapter {
|
||||
if (oldItemPosition >= mEntityList.size()) return false;
|
||||
if (newItemPosition >= updateData.size()) return false;
|
||||
|
||||
DataType oldItem = mEntityList.get(oldItemPosition);
|
||||
DataType newItem = updateData.get(newItemPosition);
|
||||
DataType oldItem = ExtensionsKt.safelyGetInRelease(mEntityList, oldItemPosition);
|
||||
DataType newItem = ExtensionsKt.safelyGetInRelease(updateData, newItemPosition);
|
||||
return ListAdapter.this.areContentsTheSame(oldItem, newItem);
|
||||
}
|
||||
});
|
||||
|
||||
@ -11,9 +11,11 @@ import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.ethanhua.skeleton.SkeletonScreen;
|
||||
import com.gh.common.util.NumberUtils;
|
||||
import com.gh.common.view.FixLinearLayoutManager;
|
||||
import com.gh.common.view.VerticalItemDecoration;
|
||||
import com.gh.gamecenter.R;
|
||||
@ -59,6 +61,9 @@ public abstract class ListFragment<T, VM extends BaseListViewModel /* 该泛型
|
||||
@Nullable
|
||||
protected SkeletonScreen mSkeletonScreen;
|
||||
|
||||
private int[] lastPositions;
|
||||
private int lastVisibleItemPosition;
|
||||
|
||||
protected abstract ListAdapter provideListAdapter();
|
||||
|
||||
protected RecyclerView.ItemDecoration getItemDecoration() {
|
||||
@ -146,6 +151,26 @@ public abstract class ListFragment<T, VM extends BaseListViewModel /* 该泛型
|
||||
&& RecyclerView.SCROLL_STATE_IDLE == newState) {
|
||||
mListViewModel.load(LoadType.NORMAL);
|
||||
}
|
||||
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
|
||||
int visibleItemCount = layoutManager.getChildCount();
|
||||
int totalItemCount = layoutManager.getItemCount();
|
||||
if ((visibleItemCount > 0 && newState == RecyclerView.SCROLL_STATE_IDLE && (lastVisibleItemPosition) >= totalItemCount - 1)) {
|
||||
mListViewModel.load(LoadType.NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||
super.onScrolled(recyclerView, dx, dy);
|
||||
|
||||
RecyclerView.LayoutManager layoutManager = mListRv.getLayoutManager();
|
||||
if (layoutManager instanceof StaggeredGridLayoutManager) {
|
||||
if (lastPositions == null) {
|
||||
lastPositions = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
|
||||
}
|
||||
((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(lastPositions);
|
||||
lastVisibleItemPosition = NumberUtils.findMax(lastPositions);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -94,8 +94,6 @@ class NewCatalogListAdapter(context: Context,
|
||||
|
||||
GameViewUtils.setLabelList(mContext, holder.binding.labelList, gameEntity.tagStyle)
|
||||
|
||||
gameEntity.sequence = position + 1
|
||||
|
||||
val sortType = mViewModel.sortType.value
|
||||
val sortSize = mViewModel.sortSize.text
|
||||
val toolbarTitle = mViewModel.title
|
||||
@ -105,7 +103,6 @@ class NewCatalogListAdapter(context: Context,
|
||||
exposureSources.add(mBaseExposureSource)
|
||||
exposureSources.add(ExposureSource(toolbarTitle))
|
||||
exposureSources.add(ExposureSource("二级分类详情", "$selectedCatalogName+$sortType+$sortSize"))
|
||||
gameEntity.sequence = position + 1
|
||||
|
||||
val event = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
|
||||
mExposureEventSparseArray.put(position, event)
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.gamecenter.catalog
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.gh.common.exposure.ExposureUtils
|
||||
import com.gh.common.util.UrlFilterUtils
|
||||
import com.gh.common.view.CatalogFilterView
|
||||
import com.gh.gamecenter.baselist.ListViewModel
|
||||
@ -35,7 +36,10 @@ class NewCatalogListViewModel(application: Application) : ListViewModel<GameEnti
|
||||
}
|
||||
|
||||
override fun mergeResultLiveData() {
|
||||
mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) }
|
||||
mResultLiveData.addSource(mListLiveData) {
|
||||
ExposureUtils.updateExposureSequence(it)
|
||||
mResultLiveData.postValue(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateSortConfig(sortSize: SubjectSettingEntity.Size? = null,
|
||||
|
||||
@ -111,7 +111,7 @@ class SpecialCatalogAdapter(context: Context, private val mCatalogViewModel: Cat
|
||||
var exposureEvent: ExposureEvent? = null
|
||||
if (imageEntity.link.type == "game") {
|
||||
exposureEvent = ExposureEvent.createEvent(
|
||||
GameEntity(id = imageEntity.link.link),
|
||||
GameEntity(id = imageEntity.link.link).apply { outerSequence = mEntityList[position].position },
|
||||
listOf(mCatalogViewModel.basicExposureSource, ExposureSource("精选页图片", "")))
|
||||
mExposureEventSparseArray.append(position, exposureEvent)
|
||||
}
|
||||
@ -144,12 +144,16 @@ class SpecialCatalogAdapter(context: Context, private val mCatalogViewModel: Cat
|
||||
val subject = mEntityList[position].subject!!
|
||||
|
||||
val exposureList = arrayListOf<ExposureEvent>()
|
||||
for (game in subject.link.data) {
|
||||
for ((index, game) in subject.link.data.withIndex()) {
|
||||
game.sequence = index
|
||||
game.subjectName = subject.link.text
|
||||
game.outerSequence = mEntityList[position].position
|
||||
|
||||
val exposureEvent = ExposureEvent.createEvent(game,
|
||||
listOf(mCatalogViewModel.basicExposureSource, ExposureSource("精选页专题", subject.link.text ?: "")))
|
||||
exposureList.add(exposureEvent)
|
||||
|
||||
game.exposureEvent = exposureEvent
|
||||
game.subjectName = subject.link.text
|
||||
}
|
||||
mEntityList[position].exposureEventList = exposureList
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ class SpecialCatalogSubjectAdapter(context: Context,
|
||||
|
||||
fun checkResetData(update: List<GameEntity>) {
|
||||
var dataIds = ""
|
||||
mList.forEach { dataIds += it.id }
|
||||
update.forEach { dataIds += it.id }
|
||||
|
||||
mList = update
|
||||
if (countAndKey?.first == update.size && countAndKey?.second != dataIds) { // 数量不变,内容发生改变
|
||||
|
||||
@ -56,7 +56,7 @@ class SpecialCatalogSubjectCollectionAdapter(context: Context,
|
||||
|
||||
fun checkResetData(update: List<GameEntity>) {
|
||||
var dataIds = ""
|
||||
mList.forEach { dataIds += it.id }
|
||||
update.forEach { dataIds += it.id }
|
||||
|
||||
mList = update
|
||||
if (countAndKey?.first == update.size && countAndKey?.second != dataIds) { // 数量不变,内容发生改变
|
||||
|
||||
@ -27,8 +27,8 @@ class CategoryDirectoryFragment : ListFragment<CategoryEntity, CategoryDirectory
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
mViewModel = ViewModelProviders.of(this).get(CategoryDirectoryListViewModel::class.java)
|
||||
mViewModel.categoryId = arguments?.getString(EntranceUtils.KEY_CATEGORY_ID)!!
|
||||
mAdapter = CategoryDirectoryAdapter(context!!, arguments?.getString(EntranceUtils.KEY_CATEGORY_TITLE)!!)
|
||||
mViewModel.categoryId = arguments?.getString(EntranceUtils.KEY_CATEGORY_ID) ?: ""
|
||||
mAdapter = CategoryDirectoryAdapter(context!!, arguments?.getString(EntranceUtils.KEY_CATEGORY_TITLE) ?: "")
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
|
||||
@ -89,8 +89,6 @@ class NewCategoryListAdapter(context: Context,
|
||||
val padTop = if (position == 0) 16F.dip2px() else 8F.dip2px()
|
||||
holder.itemView.setPadding(16F.dip2px(), padTop, 16F.dip2px(), 8F.dip2px())
|
||||
|
||||
gameEntity.sequence = position + 1
|
||||
|
||||
val sortType = if ("download:-1" == mViewModel.getSortType()) "最热" else "最新"
|
||||
val toolbarTitle = mViewModel.title
|
||||
val categoryTitle = mViewModel.categoryTitle
|
||||
@ -99,7 +97,6 @@ class NewCategoryListAdapter(context: Context,
|
||||
val exposureSources = ArrayList<ExposureSource>()
|
||||
exposureSources.add(ExposureSource(categoryTitle, selectedCategoryName))
|
||||
exposureSources.add(ExposureSource("二级分类", "$selectedCategoryName+$sortType"))
|
||||
gameEntity.sequence = position + 1
|
||||
|
||||
val event = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
|
||||
mExposureEventSparseArray.put(position, event)
|
||||
|
||||
@ -64,7 +64,7 @@ class NewCategoryListFragment : ListFragment<GameEntity, NewCategoryListViewMode
|
||||
mViewModel.categoryTitle = arguments?.getString(EntranceUtils.KEY_CATEGORY_TITLE) ?: ""
|
||||
mEntrance = arguments?.getString(EntranceUtils.KEY_ENTRANCE) ?: Constants.ENTRANCE_UNKNOWN
|
||||
mPrimeCategory = arguments?.getParcelable(EntranceUtils.KEY_DATA)
|
||||
mSubCategoryList = mPrimeCategory?.data as ArrayList<CategoryEntity>
|
||||
mSubCategoryList = mPrimeCategory?.data as? ArrayList<CategoryEntity> ?: arrayListOf()
|
||||
|
||||
val initSelectedCategory = arguments?.getString(EntranceUtils.KEY_CATEGORY_INIT_TITLE)
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.gamecenter.category
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.gh.common.exposure.ExposureUtils
|
||||
import com.gh.common.util.UrlFilterUtils
|
||||
import com.gh.common.view.ConfigFilterView
|
||||
import com.gh.gamecenter.baselist.ListViewModel
|
||||
@ -36,7 +37,10 @@ class NewCategoryListViewModel(application: Application)
|
||||
}
|
||||
|
||||
override fun mergeResultLiveData() {
|
||||
mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) }
|
||||
mResultLiveData.addSource(mListLiveData) {
|
||||
ExposureUtils.updateExposureSequence(it)
|
||||
mResultLiveData.postValue(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun changeSelectedCategory(category: CategoryEntity) {
|
||||
|
||||
@ -8,6 +8,7 @@ import com.j256.ormlite.dao.Dao;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
// TODO 这个数据库其实没有用了,上传到 loghub 已经有相关的逻辑处理,有空删掉它
|
||||
public class DataCollectionDao {
|
||||
|
||||
private DatabaseHelper helper;
|
||||
@ -17,7 +18,7 @@ public class DataCollectionDao {
|
||||
try {
|
||||
helper = DatabaseHelper.getHelper(context);
|
||||
dao = helper.getDao(DataCollectionInfo.class);
|
||||
} catch (SQLException | IllegalStateException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -28,7 +29,7 @@ public class DataCollectionDao {
|
||||
public List<DataCollectionInfo> findByType(String type) {
|
||||
try {
|
||||
return dao.queryForEq("type", type);
|
||||
} catch (SQLException | IllegalStateException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
@ -40,7 +41,7 @@ public class DataCollectionDao {
|
||||
public void add(DataCollectionInfo entity) {
|
||||
try {
|
||||
dao.create(entity);
|
||||
} catch (SQLException | IllegalStateException e) {
|
||||
} catch (Exception e) {
|
||||
// java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -52,7 +53,7 @@ public class DataCollectionDao {
|
||||
public void delete(String id) {
|
||||
try {
|
||||
dao.deleteById(id);
|
||||
} catch (SQLException | IllegalStateException e) {
|
||||
} catch (Exception e) {
|
||||
// java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -64,7 +65,7 @@ public class DataCollectionDao {
|
||||
public void delete(List<String> ids) {
|
||||
try {
|
||||
dao.deleteIds(ids);
|
||||
} catch (SQLException | IllegalStateException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -75,7 +76,7 @@ public class DataCollectionDao {
|
||||
public DataCollectionInfo find(String id) {
|
||||
try {
|
||||
return dao.queryForId(id);
|
||||
} catch (SQLException | IllegalStateException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
@ -87,7 +88,7 @@ public class DataCollectionDao {
|
||||
public List<DataCollectionInfo> getAll() {
|
||||
try {
|
||||
return dao.queryForAll();
|
||||
} catch (SQLException | IllegalStateException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
@ -99,7 +100,7 @@ public class DataCollectionDao {
|
||||
public List<DataCollectionInfo> getClickData() {
|
||||
try {
|
||||
return dao.queryForEq("type", "click-item");
|
||||
} catch (SQLException | IllegalStateException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
@ -111,7 +112,7 @@ public class DataCollectionDao {
|
||||
public void update(DataCollectionInfo entity) {
|
||||
try {
|
||||
dao.update(entity);
|
||||
} catch (SQLException | IllegalStateException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ public class FilterDao {
|
||||
try {
|
||||
helper = DatabaseHelper.getHelper(context);
|
||||
dao = helper.getDao(PackageInfo.class);
|
||||
} catch (SQLiteException | SQLException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -32,7 +32,7 @@ public class FilterDao {
|
||||
if (list != null && list.size() != 0) {
|
||||
return list.get(0).getTime();
|
||||
}
|
||||
} catch (SQLiteException | SQLException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
@ -44,7 +44,7 @@ public class FilterDao {
|
||||
if (filterEntity != null) {
|
||||
return true;
|
||||
}
|
||||
} catch (SQLiteException | SQLException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
@ -56,7 +56,7 @@ public class FilterDao {
|
||||
public void add(PackageInfo entity) {
|
||||
try {
|
||||
dao.create(entity);
|
||||
} catch (SQLiteException | SQLException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -68,7 +68,7 @@ public class FilterDao {
|
||||
public void addAll(List<PackageInfo> list) {
|
||||
try {
|
||||
dao.create(list);
|
||||
} catch (SQLiteException | SQLException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -76,7 +76,7 @@ public class FilterDao {
|
||||
public void deleteAll(List<PackageInfo> list) {
|
||||
try {
|
||||
dao.delete(list);
|
||||
} catch (SQLiteException | SQLException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -87,7 +87,7 @@ public class FilterDao {
|
||||
public void delete(String packageName) {
|
||||
try {
|
||||
dao.deleteById(packageName);
|
||||
} catch (SQLiteException | SQLException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -98,7 +98,7 @@ public class FilterDao {
|
||||
public List<PackageInfo> getAll() {
|
||||
try {
|
||||
return dao.queryForAll();
|
||||
} catch (SQLiteException | SQLException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
@ -110,7 +110,7 @@ public class FilterDao {
|
||||
public long getCount() {
|
||||
try {
|
||||
return dao.countOf();
|
||||
} catch (SQLiteException | SQLException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user