diff --git a/README.md b/README.md index 625db636..57f8652c 100644 --- a/README.md +++ b/README.md @@ -13,4 +13,6 @@ ## 说明 **本软件及源码仅供学习交流使用,严禁用于商业用途。** -本软件已停止功能性更新。 \ No newline at end of file +~~本软件已停止功能性更新。~~ + +自 2020/8/11 起,本软件单方面由 [GoFly233](https://github.com/GoFly233) 继续开发。 diff --git a/app/build.gradle b/app/build.gradle index d4b678ec..87b377b1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -69,7 +69,7 @@ android { } compileSdkVersion 29 defaultConfig { - applicationId "com.huanchengfly.tieba.post" + applicationId "top.goforce.tieba.post" minSdkVersion 21 targetSdkVersion 29 versionCode applicationVersionCode @@ -110,7 +110,7 @@ dependencies { kapt "com.android.support:support-annotations:28.0.0" //AndroidX - implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.0-rc1' implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.legacy:legacy-support-v4:1.0.0' @@ -120,6 +120,9 @@ dependencies { //Test testImplementation 'junit:junit:4.13' + androidTestImplementation 'androidx.test:core:1.2.0' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test:rules:1.2.0' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' diff --git a/app/src/androidTest/java/com/huanchengfly/tieba/post/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/huanchengfly/tieba/post/ExampleInstrumentedTest.java index 232644da..db1b5ef2 100644 --- a/app/src/androidTest/java/com/huanchengfly/tieba/post/ExampleInstrumentedTest.java +++ b/app/src/androidTest/java/com/huanchengfly/tieba/post/ExampleInstrumentedTest.java @@ -1,10 +1,7 @@ package com.huanchengfly.tieba.post; import android.content.Context; - -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - +import androidx.test.core.app.ApplicationProvider; import org.junit.Test; import org.junit.runner.RunWith; @@ -15,12 +12,12 @@ import static org.junit.Assert.assertEquals; * * @see Testing documentation */ -@RunWith(AndroidJUnit4.class) +@RunWith(androidx.test.ext.junit.runners.AndroidJUnit4.class) public class ExampleInstrumentedTest { @Test public void useAppContext() { // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); + Context appContext = ApplicationProvider.getApplicationContext(); assertEquals("com.huanchengfly.tieba.post", appContext.getPackageName()); } diff --git a/app/src/main/java/com/huanchengfly/tieba/post/MainActivity.java b/app/src/main/java/com/huanchengfly/tieba/post/MainActivity.java deleted file mode 100644 index 47530385..00000000 --- a/app/src/main/java/com/huanchengfly/tieba/post/MainActivity.java +++ /dev/null @@ -1,556 +0,0 @@ -package com.huanchengfly.tieba.post; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.job.JobInfo; -import android.app.job.JobScheduler; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.graphics.Typeface; -import android.os.Bundle; -import android.os.Handler; -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.text.TextUtils; -import android.text.style.ForegroundColorSpan; -import android.text.style.StyleSpan; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.viewpager.widget.ViewPager; - -import com.google.android.material.bottomnavigation.BottomNavigationItemView; -import com.google.android.material.bottomnavigation.BottomNavigationMenuView; -import com.google.android.material.bottomnavigation.BottomNavigationView; -import com.google.android.material.snackbar.Snackbar; -import com.huanchengfly.tieba.api.Error; -import com.huanchengfly.tieba.api.LiteApi; -import com.huanchengfly.tieba.api.interfaces.CommonAPICallback; -import com.huanchengfly.tieba.api.interfaces.CommonCallback; -import com.huanchengfly.tieba.api.models.ChangelogBean; -import com.huanchengfly.tieba.api.models.NewUpdateBean; -import com.huanchengfly.tieba.post.activities.NewIntroActivity; -import com.huanchengfly.tieba.post.activities.UpdateInfoActivity; -import com.huanchengfly.tieba.post.activities.base.BaseActivity; -import com.huanchengfly.tieba.post.adapters.MainSearchAdapter; -import com.huanchengfly.tieba.post.adapters.ViewPagerAdapter; -import com.huanchengfly.tieba.post.base.BaseApplication; -import com.huanchengfly.tieba.post.fragments.BaseFragment; -import com.huanchengfly.tieba.post.fragments.ForumListFragment; -import com.huanchengfly.tieba.post.fragments.MessageFragment; -import com.huanchengfly.tieba.post.fragments.MyInfoFragment; -import com.huanchengfly.tieba.post.fragments.PersonalizedFeedFragment; -import com.huanchengfly.tieba.post.interfaces.Refreshable; -import com.huanchengfly.tieba.post.models.MyInfoBean; -import com.huanchengfly.tieba.post.models.database.SearchHistory; -import com.huanchengfly.tieba.post.services.NotifyJobService; -import com.huanchengfly.tieba.post.utils.AccountUtil; -import com.huanchengfly.tieba.post.utils.DialogUtil; -import com.huanchengfly.tieba.post.utils.DisplayUtil; -import com.huanchengfly.tieba.post.utils.HandleBackUtil; -import com.huanchengfly.tieba.post.utils.JobServiceUtil; -import com.huanchengfly.tieba.post.utils.NavigationHelper; -import com.huanchengfly.tieba.post.utils.ReceiverUtil; -import com.huanchengfly.tieba.post.utils.SharedPreferencesUtil; -import com.huanchengfly.tieba.post.utils.ThemeUtil; -import com.huanchengfly.tieba.post.utils.TiebaUtil; -import com.huanchengfly.tieba.post.utils.Util; -import com.huanchengfly.tieba.post.utils.VersionUtil; -import com.huanchengfly.tieba.widgets.MyViewPager; -import com.huanchengfly.tieba.widgets.theme.TintToolbar; -import com.lapism.searchview.Search; -import com.lapism.searchview.widget.SearchView; - -import java.util.List; - -import static com.huanchengfly.tieba.post.utils.ThemeUtil.THEME_TRANSLUCENT; - -public class MainActivity extends BaseActivity implements BottomNavigationView.OnNavigationItemSelectedListener, MainSearchAdapter.OnSearchItemClickListener, BottomNavigationView.OnNavigationItemReselectedListener { - public static final String TAG = "MainActivity"; - public static final String SP_SHOULD_SHOW_SNACKBAR = "should_show_snackbar"; - private static Handler handler = new Handler(); - public ViewPagerAdapter mAdapter = new ViewPagerAdapter(getSupportFragmentManager()); - private TintToolbar mToolbar; - private MyViewPager mViewPager; - private BottomNavigationView mBottomNavigationView; - private BottomNavigationMenuView menuView; - private SearchView mSearchView; - private long lastTime = 0; - private NavigationHelper navigationHelper; - private boolean hideExplore; - private TextView badgeTextView; - private BroadcastReceiver newMessageReceiver = new NewMessageReceiver(); - private BroadcastReceiver accountSwitchReceiver = new AccountSwitchReceiver(); - private FrameLayout appbar; - private MainSearchAdapter mSearchAdapter; - - @Override - public void onResume() { - String reason = ThemeUtil.getSharedPreferences(this).getString(ThemeUtil.SP_SWITCH_REASON, null); - boolean followSystemNight = SharedPreferencesUtil.get(this, SharedPreferencesUtil.SP_SETTINGS) - .getBoolean("follow_system_night", false) && !TextUtils.equals(reason, ThemeUtil.REASON_MANUALLY); - if (followSystemNight) { - if (BaseApplication.isSystemNight() && !ThemeUtil.isNightMode(this)) { - SharedPreferencesUtil.put(ThemeUtil.getSharedPreferences(this), SP_SHOULD_SHOW_SNACKBAR, true); - ThemeUtil.switchToNightMode(this, ThemeUtil.REASON_FOLLOW_SYSTEM, false); - } else if (!BaseApplication.isSystemNight() && ThemeUtil.isNightMode(this) && TextUtils.equals(reason, ThemeUtil.REASON_FOLLOW_SYSTEM)) { - SharedPreferencesUtil.put(ThemeUtil.getSharedPreferences(this), SP_SHOULD_SHOW_SNACKBAR, true); - ThemeUtil.switchFromNightMode(this, ThemeUtil.REASON_FOLLOW_SYSTEM, false); - } - } - super.onResume(); - refreshSearchView(); - ThemeUtil.setTranslucentThemeBackground(findViewById(R.id.background)); - if (THEME_TRANSLUCENT.equals(ThemeUtil.getTheme(this))) { - mBottomNavigationView.setElevation(0f); - } else { - mBottomNavigationView.setElevation(DisplayUtil.dp2px(this, 4)); - } - } - - @Override - public void onNavigationItemReselected(@NonNull MenuItem item) { - BaseFragment fragment = mAdapter.getCurrentFragment(); - if (fragment instanceof Refreshable) { - ((Refreshable) fragment).onRefresh(); - } - } - - public void openSearch() { - mSearchView.open(null); - } - - @Override - public boolean onNavigationItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case R.id.navbar_home: - mViewPager.setCurrentItem(0, false); - return true; - case R.id.navbar_explore: - if (!hideExplore) { - mViewPager.setCurrentItem(1, false); - } - return true; - case R.id.navbar_msg: - mViewPager.setCurrentItem(hideExplore ? 1 : 2, false); - return true; - case R.id.navbar_user: - mViewPager.setCurrentItem(hideExplore ? 2 : 3, false); - return true; - } - return false; - } - - protected void findView() { - appbar = (FrameLayout) findViewById(R.id.appbar); - mToolbar = (TintToolbar) findViewById(R.id.toolbar); - mSearchView = (SearchView) findViewById(R.id.toolbar_search_view); - mBottomNavigationView = (BottomNavigationView) findViewById(R.id.navbar); - menuView = (BottomNavigationMenuView) mBottomNavigationView.getChildAt(0); - mViewPager = (MyViewPager) findViewById(R.id.mViewPager); - /* - int[][] states = new int[2][]; - states[0] = new int[] { android.R.attr.state_checked }; - states[1] = new int[] {}; - int color = Util.getColorByStyle(this, R.styleable.Theme_colorAccent, R.color.colorAccent); - mBottomNavigationView.setItemIconTintList(new ColorStateList(states, new int[]{color, getLighterColor(color, 0.2f)})); - mBottomNavigationView.setItemTextColor(new ColorStateList(states, new int[]{color, getLighterColor(color, 0.2f)})); - mBottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_AUTO); - */ - } - - protected void initView() { - mSearchAdapter = new MainSearchAdapter(this); - mSearchAdapter.setOnSearchItemClickListener(this); - mSearchView.setAdapter(mSearchAdapter); - BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(hideExplore ? 1 : 2); - View badge = LayoutInflater.from(MainActivity.this).inflate(R.layout.layout_badge, menuView, false); - itemView.addView(badge); - badgeTextView = badge.findViewById(R.id.tv_msg_count); - navigationHelper = NavigationHelper.newInstance(this); - setSupportActionBar(mToolbar); - hideExplore = getSharedPreferences("settings", MODE_PRIVATE).getBoolean("hideExplore", false); - if (hideExplore) { - mBottomNavigationView.getMenu().removeItem(R.id.navbar_explore); - } - ForumListFragment fragmentHome = new ForumListFragment(); - mAdapter.addFragment(fragmentHome); - if (!hideExplore) { - PersonalizedFeedFragment personalizedFeedFragment = new PersonalizedFeedFragment(); - mAdapter.addFragment(personalizedFeedFragment); - } - MessageFragment messageFragment = MessageFragment.newInstance(MessageFragment.TYPE_REPLY_ME); - mAdapter.addFragment(messageFragment); - MyInfoFragment fragmentMine = new MyInfoFragment(); - mAdapter.addFragment(fragmentMine); - mViewPager.setCanScroll(false); - mViewPager.setAdapter(mAdapter); - mViewPager.setOffscreenPageLimit(mAdapter.getCount()); - refreshSearchView(); - } - - @Override - public void refreshGlobal(Activity activity) { - super.refreshGlobal(activity); - refreshSearchView(); - } - - protected void refreshSearchView() { - if (mSearchView == null) { - return; - } - mSearchAdapter.refreshData(); - mSearchView.setTheme(ThemeUtil.isNightMode(this) || THEME_TRANSLUCENT.equals(ThemeUtil.getTheme(this)) ? Search.Theme.DARK : Search.Theme.LIGHT); - } - - protected void initListener() { - mBottomNavigationView.setOnNavigationItemSelectedListener(this); - mBottomNavigationView.setOnNavigationItemReselectedListener(this); - mSearchView.setOnQueryTextListener(new Search.OnQueryTextListener() { - @Override - public void onQueryTextChange(CharSequence newText) { - } - - @Override - public boolean onQueryTextSubmit(CharSequence key) { - startActivity(new Intent(MainActivity.this, SearchActivity.class) - .putExtra(SearchActivity.EXTRA_KEYWORD, key.toString())); - new SearchHistory(key.toString()) - .saveOrUpdate("content = ?", key.toString()); - return true; - } - }); - mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - } - - @SuppressLint("RestrictedApi") - @Override - public void onPageSelected(int position) { - BaseFragment baseFragment = mAdapter.getItem(position); - appbar.setVisibility(baseFragment.hasOwnAppbar() ? View.GONE : View.VISIBLE); - mBottomNavigationView.getMenu().getItem(position).setChecked(true); - mToolbar.setTitle(mBottomNavigationView.getMenu().getItem(position).getTitle()); - if (position == (hideExplore ? 1 : 2)) { - badgeTextView.setVisibility(View.GONE); - } - } - - @Override - public void onPageScrollStateChanged(int state) { - } - }); - } - - @SuppressLint("ApplySharedPref") - protected void clearSwitchReason() { - if (TextUtils.equals(ThemeUtil.getSharedPreferences(this).getString(ThemeUtil.SP_SWITCH_REASON, null), ThemeUtil.REASON_MANUALLY)) { - ThemeUtil.getSharedPreferences(this).edit().remove(ThemeUtil.SP_SWITCH_REASON).commit(); - } - } - - protected boolean shouldShowSwitchSnackbar() { - return ThemeUtil.getSharedPreferences(this).getBoolean(SP_SHOULD_SHOW_SNACKBAR, false); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setSwipeBackEnable(false); - setContentView(R.layout.activity_main); - ThemeUtil.setTranslucentThemeBackground(findViewById(R.id.background)); - findView(); - initView(); - initListener(); - if (!SharedPreferencesUtil.get(SharedPreferencesUtil.SP_APP_DATA).getBoolean("notice_dialog", false)) { - showDialog(DialogUtil.build(this) - .setTitle(R.string.title_dialog_notice) - .setMessage(R.string.message_dialog_notice) - .setPositiveButton(R.string.button_sure_default, (dialog, which) -> SharedPreferencesUtil.put(this, SharedPreferencesUtil.SP_APP_DATA, "notice_dialog", true)) - .setCancelable(false) - .create()); - } - if (savedInstanceState == null) { - clearSwitchReason(); - } - if (shouldShowSwitchSnackbar()) { - Util.createSnackbar(mViewPager, ThemeUtil.isNightMode(this) ? R.string.snackbar_auto_switch_to_night : R.string.snackbar_auto_switch_from_night, Snackbar.LENGTH_SHORT) - .show(); - SharedPreferencesUtil.put(ThemeUtil.getSharedPreferences(this), SP_SHOULD_SHOW_SNACKBAR, false); - } - handler.postDelayed(() -> { - checkUpdate(); - try { - TiebaUtil.initAutoSign(this); - } catch (Exception e) { - e.printStackTrace(); - } - if (AccountUtil.isLoggedIn(this) && AccountUtil.getCookie(this) == null) { - showDialog(DialogUtil.build(this) - .setTitle(R.string.title_dialog_update_stoken) - .setMessage(R.string.message_dialog_update_stoken) - .setPositiveButton(R.string.button_sure_default, (dialog, which) -> startActivity(UpdateInfoActivity.newIntent(this, UpdateInfoActivity.ACTION_UPDATE_LOGIN_INFO))) - .setCancelable(false) - .create()); - } - AccountUtil.updateUserInfo(this, new CommonCallback() { - @Override - public void onSuccess(MyInfoBean data) { - } - - @Override - public void onFailure(int code, String error) { - if (code == Error.ERROR_LOGGED_IN_EXPIRED) { - showDialog(DialogUtil.build(MainActivity.this) - .setTitle(R.string.title_dialog_logged_in_expired) - .setMessage(R.string.message_dialog_logged_in_expired) - .setPositiveButton(R.string.button_ok, (dialog, which) -> { - navigationHelper.navigationByData(NavigationHelper.ACTION_LOGIN); - }) - .setCancelable(false) - .create()); - } - } - }); - }, 1000); - if (BaseApplication.isFirstRun()) { - startActivity(new Intent(this, NewIntroActivity.class)); - } else if (!AccountUtil.isLoggedIn(this)) { - navigationHelper.navigationByData(NavigationHelper.ACTION_LOGIN); - } - /* - handler.postDelayed(() -> { - try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - String relativePath = Environment.DIRECTORY_PICTURES + File.separator + "Tieba Lite" + File.separator + "shareTemp"; - String where = MediaStore.Images.Media.RELATIVE_PATH + " like \"" + relativePath + "%" + "\""; - int i = getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, where, null); - } else { - if (AndPermission.hasPermissions(this, Permission.Group.STORAGE)) { - File shareTemp = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsoluteFile(), "Tieba Lite" + File.separator + "shareTemp"); - if (shareTemp.exists() && shareTemp.delete()) { - FileUtil.deleteAllFiles(shareTemp); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - }, 100); - */ - } - - @Override - public void recreate() { - super.recreate(); - Log.i(TAG, "recreate: "); - } - - @Override - protected void onStart() { - super.onStart(); - registerReceiver(newMessageReceiver, ReceiverUtil.createIntentFilter(NotifyJobService.ACTION_NEW_MESSAGE)); - registerReceiver(accountSwitchReceiver, ReceiverUtil.createIntentFilter(AccountUtil.ACTION_SWITCH_ACCOUNT)); - try { - startService(new Intent(this, NotifyJobService.class)); - JobInfo.Builder builder = new JobInfo.Builder(JobServiceUtil.getJobId(this), new ComponentName(this, NotifyJobService.class)) - .setPersisted(true) - .setPeriodic(30 * 60 * 1000L) - .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); - JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); - if (jobScheduler != null) jobScheduler.schedule(builder.build()); - } catch (Exception ignored) { - } - } - - @Override - protected void onStop() { - try { - stopService(new Intent(this, NotifyJobService.class)); - } catch (Exception ignored) { - } - unregisterReceiver(newMessageReceiver); - unregisterReceiver(accountSwitchReceiver); - super.onStop(); - } - - private void checkUpdate() { - int oldVersion = SharedPreferencesUtil.get(this, SharedPreferencesUtil.SP_APP_DATA).getInt("version", -1); - if (oldVersion < VersionUtil.getVersionCode(this)) { - LiteApi.getInstance().changelog(new CommonAPICallback() { - @Override - public void onSuccess(ChangelogBean data) { - SharedPreferencesUtil.get(MainActivity.this, SharedPreferencesUtil.SP_APP_DATA) - .edit() - .putInt("version", VersionUtil.getVersionCode(MainActivity.this)) - .apply(); - if (!TextUtils.isEmpty(data.getResult())) { - showDialog(DialogUtil.build(MainActivity.this) - .setTitle(R.string.title_dialog_changelog) - .setMessage(data.getResult()) - .setPositiveButton(R.string.button_ok, null) - .create()); - } - } - - @Override - public void onFailure(int code, String error) { - - } - }); - } - LiteApi.getInstance().newCheckUpdate(new CommonAPICallback() { - @Override - public void onSuccess(NewUpdateBean data) { - if (data.isHasUpdate()) { - boolean cancelable = data.getResult().isCancelable(); - boolean ignored = SharedPreferencesUtil.get(MainActivity.this, SharedPreferencesUtil.SP_IGNORE_VERSIONS) - .getBoolean(data.getResult().getVersionName() + "_" + data.getResult().getVersionCode(), false); - if (ignored && cancelable) { - return; - } - SpannableStringBuilder builder = new SpannableStringBuilder(); - if (data.getResult().getVersionType() == 1) { - String betaTip = getString(R.string.tip_beta_version); - builder.append(betaTip, new ForegroundColorSpan(getResources().getColor(R.color.red)), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - builder.setSpan(new StyleSpan(Typeface.BOLD), 0, betaTip.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } - for (String content : data.getResult().getUpdateContent()) { - builder.append(content); - builder.append("\n"); - } - AlertDialog.Builder dialogBuilder = DialogUtil.build(MainActivity.this) - .setTitle(getString(R.string.title_dialog_update, data.getResult().getVersionName())) - .setMessage(builder) - .setPositiveButton(R.string.button_go_to_download, (dialog, which) -> { - VersionUtil.showDownloadDialog(MainActivity.this, data.getResult()); - }) - .setCancelable(cancelable); - if (cancelable) { - dialogBuilder.setNegativeButton(R.string.button_next_time, null); - dialogBuilder.setNeutralButton(R.string.button_ignore_this_version, (dialog, which) -> SharedPreferencesUtil.get(MainActivity.this, SharedPreferencesUtil.SP_IGNORE_VERSIONS) - .edit() - .putBoolean(data.getResult().getVersionName() + "_" + data.getResult().getVersionCode(), true) - .apply()); - } - showDialog(dialogBuilder.create()); - } - } - - @Override - public void onFailure(int code, String error) { - } - }); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.toolbar_menu, menu); - return super.onCreateOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.menu_sign: - TiebaUtil.startSign(MainActivity.this); - return true; - case R.id.action_search: - mSearchView.open(item); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public void onBackPressed() { - if (mSearchView.isOpen()) { - mSearchView.close(); - } else { - if (!HandleBackUtil.handleBackPress(this)) { - exit(); - } - } - } - - public void exit(boolean isDouble) { - if (!isDouble || System.currentTimeMillis() - lastTime < 2000) { - exitApplication(); - } else { - lastTime = System.currentTimeMillis(); - Toast.makeText(this, R.string.toast_double_key_exit, Toast.LENGTH_SHORT).show(); - } - } - - public void exit() { - exit(true); - } - - @Override - public void setTitle(String newTitle) { - mToolbar.setTitle(newTitle); - } - - @Override - public void onSearchItemClick(int position, CharSequence content) { - startActivity(new Intent(MainActivity.this, SearchActivity.class) - .putExtra(SearchActivity.EXTRA_KEYWORD, content.toString())); - new SearchHistory(content.toString()) - .saveOrUpdate("content = ?", content.toString()); - refreshSearchView(); - } - - private class NewMessageReceiver extends BroadcastReceiver { - @SuppressLint("RestrictedApi") - @Override - public void onReceive(Context context, Intent intent) { - try { - String action = intent.getAction(); - if (action != null && action.equals(NotifyJobService.ACTION_NEW_MESSAGE)) { - String channel = intent.getStringExtra("channel"); - int count = intent.getIntExtra("count", 0); - if (channel != null && channel.equals(NotifyJobService.CHANNEL_TOTAL) && badgeTextView != null) { - badgeTextView.setText(String.valueOf(count)); - if (count > 0) { - badgeTextView.setVisibility(View.VISIBLE); - } - } - } - } catch (Exception ignored) { - } - } - } - - private class AccountSwitchReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action != null && action.equals(AccountUtil.ACTION_SWITCH_ACCOUNT)) { - if (mAdapter == null) { - return; - } - List fragments = mAdapter.getFragments(); - for (BaseFragment fragment : fragments) { - if (fragment != null) { - try { - fragment.onAccountSwitch(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/MainActivity.kt b/app/src/main/java/com/huanchengfly/tieba/post/MainActivity.kt new file mode 100644 index 00000000..7b211ba9 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/MainActivity.kt @@ -0,0 +1,509 @@ +package com.huanchengfly.tieba.post + +import android.annotation.SuppressLint +import android.app.Activity +import android.app.job.JobInfo +import android.app.job.JobScheduler +import android.content.* +import android.graphics.Typeface +import android.os.Bundle +import android.os.Handler +import android.text.SpannableStringBuilder +import android.text.Spanned +import android.text.TextUtils +import android.text.style.ForegroundColorSpan +import android.text.style.StyleSpan +import android.util.Log +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuItem +import android.view.View +import android.widget.FrameLayout +import android.widget.TextView +import android.widget.Toast +import androidx.viewpager.widget.ViewPager.OnPageChangeListener +import com.google.android.material.bottomnavigation.BottomNavigationItemView +import com.google.android.material.bottomnavigation.BottomNavigationMenuView +import com.google.android.material.bottomnavigation.BottomNavigationView +import com.google.android.material.bottomnavigation.BottomNavigationView.OnNavigationItemReselectedListener +import com.google.android.material.snackbar.Snackbar +import com.huanchengfly.tieba.api.Error +import com.huanchengfly.tieba.api.LiteApi.Companion.instance +import com.huanchengfly.tieba.api.interfaces.CommonAPICallback +import com.huanchengfly.tieba.api.interfaces.CommonCallback +import com.huanchengfly.tieba.api.models.ChangelogBean +import com.huanchengfly.tieba.api.models.NewUpdateBean +import com.huanchengfly.tieba.post.activities.NewIntroActivity +import com.huanchengfly.tieba.post.activities.UpdateInfoActivity +import com.huanchengfly.tieba.post.activities.base.BaseActivity +import com.huanchengfly.tieba.post.adapters.MainSearchAdapter +import com.huanchengfly.tieba.post.adapters.ViewPagerAdapter +import com.huanchengfly.tieba.post.base.BaseApplication +import com.huanchengfly.tieba.post.fragments.ForumListFragment +import com.huanchengfly.tieba.post.fragments.MessageFragment +import com.huanchengfly.tieba.post.fragments.MyInfoFragment +import com.huanchengfly.tieba.post.fragments.PersonalizedFeedFragment +import com.huanchengfly.tieba.post.interfaces.Refreshable +import com.huanchengfly.tieba.post.models.MyInfoBean +import com.huanchengfly.tieba.post.models.database.SearchHistory +import com.huanchengfly.tieba.post.services.NotifyJobService +import com.huanchengfly.tieba.post.utils.* +import com.huanchengfly.tieba.widgets.MyViewPager +import com.huanchengfly.tieba.widgets.theme.TintToolbar +import com.lapism.searchview.Search +import com.lapism.searchview.widget.SearchView + +open class MainActivity : BaseActivity(), BottomNavigationView.OnNavigationItemSelectedListener, MainSearchAdapter.OnSearchItemClickListener, OnNavigationItemReselectedListener { + var mAdapter: ViewPagerAdapter? = ViewPagerAdapter(supportFragmentManager) + private var mToolbar: TintToolbar? = null + private var mViewPager: MyViewPager? = null + private var mBottomNavigationView: BottomNavigationView? = null + private var menuView: BottomNavigationMenuView? = null + private var mSearchView: SearchView? = null + private var lastTime: Long = 0 + private var navigationHelper: NavigationHelper? = null + private var hideExplore = false + private var badgeTextView: TextView? = null + private val newMessageReceiver: BroadcastReceiver = NewMessageReceiver() + private val accountSwitchReceiver: BroadcastReceiver = AccountSwitchReceiver() + private var appbar: FrameLayout? = null + private var mSearchAdapter: MainSearchAdapter? = null + public override fun onResume() { + val reason = ThemeUtil.getSharedPreferences(this).getString(ThemeUtil.SP_SWITCH_REASON, null) + val followSystemNight = SharedPreferencesUtil.get(this, SharedPreferencesUtil.SP_SETTINGS) + .getBoolean("follow_system_night", false) && !TextUtils.equals(reason, ThemeUtil.REASON_MANUALLY) + if (followSystemNight) { + if (BaseApplication.isSystemNight() && !ThemeUtil.isNightMode(this)) { + SharedPreferencesUtil.put(ThemeUtil.getSharedPreferences(this), SP_SHOULD_SHOW_SNACKBAR, true) + ThemeUtil.switchToNightMode(this, ThemeUtil.REASON_FOLLOW_SYSTEM, false) + } else if (!BaseApplication.isSystemNight() && ThemeUtil.isNightMode(this) && TextUtils.equals(reason, ThemeUtil.REASON_FOLLOW_SYSTEM)) { + SharedPreferencesUtil.put(ThemeUtil.getSharedPreferences(this), SP_SHOULD_SHOW_SNACKBAR, true) + ThemeUtil.switchFromNightMode(this, ThemeUtil.REASON_FOLLOW_SYSTEM, false) + } + } + super.onResume() + refreshSearchView() + ThemeUtil.setTranslucentThemeBackground(findViewById(R.id.background)) + if (ThemeUtil.THEME_TRANSLUCENT == ThemeUtil.getTheme(this)) { + mBottomNavigationView!!.elevation = 0f + } else { + mBottomNavigationView!!.elevation = DisplayUtil.dp2px(this, 4f).toFloat() + } + } + + override fun onNavigationItemReselected(item: MenuItem) { + val fragment = mAdapter!!.currentFragment + if (fragment is Refreshable) { + (fragment as Refreshable).onRefresh() + } + } + + fun openSearch() { + mSearchView!!.open(null) + } + + override fun onNavigationItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + R.id.navbar_home -> { + mViewPager!!.setCurrentItem(0, false) + return true + } + R.id.navbar_explore -> { + if (!hideExplore) { + mViewPager!!.setCurrentItem(1, false) + } + return true + } + R.id.navbar_msg -> { + mViewPager!!.setCurrentItem(if (hideExplore) 1 else 2, false) + return true + } + R.id.navbar_user -> { + mViewPager!!.setCurrentItem(if (hideExplore) 2 else 3, false) + return true + } + } + return false + } + + private fun findView() { + appbar = findViewById(R.id.appbar) as FrameLayout + mToolbar = findViewById(R.id.toolbar) as TintToolbar + mSearchView = findViewById(R.id.toolbar_search_view) as SearchView + mBottomNavigationView = findViewById(R.id.navbar) as BottomNavigationView + menuView = mBottomNavigationView!!.getChildAt(0) as BottomNavigationMenuView + mViewPager = findViewById(R.id.mViewPager) as MyViewPager + /* + int[][] states = new int[2][]; + states[0] = new int[] { android.R.attr.state_checked }; + states[1] = new int[] {}; + int color = Util.getColorByStyle(this, R.styleable.Theme_colorAccent, R.color.colorAccent); + mBottomNavigationView.setItemIconTintList(new ColorStateList(states, new int[]{color, getLighterColor(color, 0.2f)})); + mBottomNavigationView.setItemTextColor(new ColorStateList(states, new int[]{color, getLighterColor(color, 0.2f)})); + mBottomNavigationView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_AUTO); + */ + } + + protected fun initView() { + mSearchAdapter = MainSearchAdapter(this) + mSearchAdapter!!.onSearchItemClickListener = this + mSearchView!!.adapter = mSearchAdapter + val itemView = menuView!!.getChildAt(if (hideExplore) 1 else 2) as BottomNavigationItemView + val badge = LayoutInflater.from(this@MainActivity).inflate(R.layout.layout_badge, menuView, false) + itemView.addView(badge) + badgeTextView = badge.findViewById(R.id.tv_msg_count) + navigationHelper = NavigationHelper.newInstance(this) + setSupportActionBar(mToolbar) + hideExplore = getSharedPreferences("settings", Context.MODE_PRIVATE).getBoolean("hideExplore", false) + if (hideExplore) { + mBottomNavigationView!!.menu.removeItem(R.id.navbar_explore) + } + val fragmentHome = ForumListFragment() + mAdapter!!.addFragment(fragmentHome) + if (!hideExplore) { + val personalizedFeedFragment = PersonalizedFeedFragment() + mAdapter!!.addFragment(personalizedFeedFragment) + } + val messageFragment = MessageFragment.newInstance(MessageFragment.TYPE_REPLY_ME) + mAdapter!!.addFragment(messageFragment) + val fragmentMine = MyInfoFragment() + mAdapter!!.addFragment(fragmentMine) + mViewPager!!.isCanScroll = false + mViewPager!!.adapter = mAdapter + mViewPager!!.offscreenPageLimit = mAdapter!!.count + refreshSearchView() + } + + override fun refreshGlobal(activity: Activity) { + super.refreshGlobal(activity) + refreshSearchView() + } + + private fun refreshSearchView() { + if (mSearchView == null) { + return + } + mSearchAdapter!!.refreshData() + mSearchView!!.theme = if (ThemeUtil.isNightMode(this) || ThemeUtil.THEME_TRANSLUCENT == ThemeUtil.getTheme(this)) Search.Theme.DARK else Search.Theme.LIGHT + } + + protected fun initListener() { + mBottomNavigationView!!.setOnNavigationItemSelectedListener(this) + mBottomNavigationView!!.setOnNavigationItemReselectedListener(this) + mSearchView!!.setOnQueryTextListener(object : Search.OnQueryTextListener { + override fun onQueryTextChange(newText: CharSequence) {} + override fun onQueryTextSubmit(key: CharSequence): Boolean { + startActivity(Intent(this@MainActivity, SearchActivity::class.java) + .putExtra(SearchActivity.EXTRA_KEYWORD, key.toString())) + SearchHistory(key.toString()) + .saveOrUpdate("content = ?", key.toString()) + return true + } + }) + mViewPager!!.addOnPageChangeListener(object : OnPageChangeListener { + override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} + + @SuppressLint("RestrictedApi") + override fun onPageSelected(position: Int) { + val baseFragment = mAdapter!!.getItem(position) + appbar!!.visibility = if (baseFragment.hasOwnAppbar()) View.GONE else View.VISIBLE + mBottomNavigationView!!.menu.getItem(position).isChecked = true + mToolbar!!.title = mBottomNavigationView!!.menu.getItem(position).title + if (position == (if (hideExplore) 1 else 2)) { + badgeTextView!!.visibility = View.GONE + } + } + + override fun onPageScrollStateChanged(state: Int) {} + }) + } + + @SuppressLint("ApplySharedPref") + protected fun clearSwitchReason() { + if (TextUtils.equals(ThemeUtil.getSharedPreferences(this).getString(ThemeUtil.SP_SWITCH_REASON, null), ThemeUtil.REASON_MANUALLY)) { + ThemeUtil.getSharedPreferences(this).edit().remove(ThemeUtil.SP_SWITCH_REASON).commit() + } + } + + protected fun shouldShowSwitchSnackbar(): Boolean { + return ThemeUtil.getSharedPreferences(this).getBoolean(SP_SHOULD_SHOW_SNACKBAR, false) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setSwipeBackEnable(false) + setContentView(R.layout.activity_main) + ThemeUtil.setTranslucentThemeBackground(findViewById(R.id.background)) + findView() + initView() + initListener() + if (!SharedPreferencesUtil.get(SharedPreferencesUtil.SP_APP_DATA).getBoolean("notice_dialog", false)) { + showDialog(DialogUtil.build(this) + .setTitle(R.string.title_dialog_notice) + .setMessage(R.string.message_dialog_notice) + .setPositiveButton(R.string.button_sure_default) { _: DialogInterface?, + _: Int -> + SharedPreferencesUtil.put(this, SharedPreferencesUtil.SP_APP_DATA, "notice_dialog", true) + } + .setCancelable(false) + .create()) + } + if (savedInstanceState == null) { + clearSwitchReason() + } + if (shouldShowSwitchSnackbar()) { + Util.createSnackbar(mViewPager!!, if (ThemeUtil.isNightMode(this)) R.string.snackbar_auto_switch_to_night else R.string.snackbar_auto_switch_from_night, Snackbar.LENGTH_SHORT) + .show() + SharedPreferencesUtil.put(ThemeUtil.getSharedPreferences(this), SP_SHOULD_SHOW_SNACKBAR, false) + } + handler.postDelayed({ + checkUpdate() + try { + TiebaUtil.initAutoSign(this) + } catch (e: Exception) { + e.printStackTrace() + } + if (AccountUtil.isLoggedIn(this) && AccountUtil.getCookie(this) == null) { + showDialog(DialogUtil.build(this) + .setTitle(R.string.title_dialog_update_stoken) + .setMessage(R.string.message_dialog_update_stoken) + .setPositiveButton(R.string.button_sure_default) { _: DialogInterface?, _: Int -> startActivity(UpdateInfoActivity.newIntent(this, UpdateInfoActivity.ACTION_UPDATE_LOGIN_INFO)) } + .setCancelable(false) + .create()) + } + AccountUtil.updateUserInfo(this, object : CommonCallback { + override fun onSuccess(data: MyInfoBean?) {} + override fun onFailure(code: Int, error: String) { + if (code == Error.ERROR_LOGGED_IN_EXPIRED) { + showDialog(DialogUtil.build(this@MainActivity) + .setTitle(R.string.title_dialog_logged_in_expired) + .setMessage(R.string.message_dialog_logged_in_expired) + .setPositiveButton(R.string.button_ok) { _: DialogInterface?, _: Int -> navigationHelper!!.navigationByData(NavigationHelper.ACTION_LOGIN) } + .setCancelable(false) + .create()) + } + } + }) + }, 1000) + if (BaseApplication.isFirstRun()) { + startActivity(Intent(this, NewIntroActivity::class.java)) + } else if (!AccountUtil.isLoggedIn(this)) { + navigationHelper!!.navigationByData(NavigationHelper.ACTION_LOGIN) + } + /* + handler.postDelayed(() -> { + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + String relativePath = Environment.DIRECTORY_PICTURES + File.separator + "Tieba Lite" + File.separator + "shareTemp"; + String where = MediaStore.Images.Media.RELATIVE_PATH + " like \"" + relativePath + "%" + "\""; + int i = getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, where, null); + } else { + if (AndPermission.hasPermissions(this, Permission.Group.STORAGE)) { + File shareTemp = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsoluteFile(), "Tieba Lite" + File.separator + "shareTemp"); + if (shareTemp.exists() && shareTemp.delete()) { + FileUtil.deleteAllFiles(shareTemp); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + }, 100); + */ + } + + override fun recreate() { + super.recreate() + Log.i(TAG, "recreate: ") + } + + override fun onStart() { + super.onStart() + registerReceiver(newMessageReceiver, ReceiverUtil.createIntentFilter(NotifyJobService.ACTION_NEW_MESSAGE)) + registerReceiver(accountSwitchReceiver, ReceiverUtil.createIntentFilter(AccountUtil.ACTION_SWITCH_ACCOUNT)) + try { + startService(Intent(this, NotifyJobService::class.java)) + val builder = JobInfo.Builder(JobServiceUtil.getJobId(this), ComponentName(this, NotifyJobService::class.java)) + .setPersisted(true) + .setPeriodic(30 * 60 * 1000L) + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) + val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler + jobScheduler.schedule(builder.build()) + } catch (ignored: Exception) { + } + } + + override fun onStop() { + try { + stopService(Intent(this, NotifyJobService::class.java)) + } catch (ignored: Exception) { + } + unregisterReceiver(newMessageReceiver) + unregisterReceiver(accountSwitchReceiver) + super.onStop() + } + + private fun checkUpdate() { + val oldVersion = SharedPreferencesUtil.get(this, SharedPreferencesUtil.SP_APP_DATA).getInt("version", -1) + if (oldVersion < VersionUtil.getVersionCode(this)) { + instance!!.changelog(object : CommonAPICallback { + override fun onSuccess(data: ChangelogBean?) { + SharedPreferencesUtil.get(this@MainActivity, SharedPreferencesUtil.SP_APP_DATA) + .edit() + .putInt("version", VersionUtil.getVersionCode(this@MainActivity)) + .apply() + if (data != null) { + if (!TextUtils.isEmpty(data.result)) { + showDialog(DialogUtil.build(this@MainActivity) + .setTitle(R.string.title_dialog_changelog) + .setMessage(data.result) + .setPositiveButton(R.string.button_ok, null) + .create()) + } + } + } + + override fun onFailure(code: Int, error: String) {} + }) + } + instance!!.newCheckUpdate(object : CommonAPICallback { + override fun onSuccess(data: NewUpdateBean?) { + if (data != null) { + if (data.isHasUpdate) { + val cancelable = data.result.isCancelable + val ignored = SharedPreferencesUtil.get(this@MainActivity, SharedPreferencesUtil.SP_IGNORE_VERSIONS) + .getBoolean(data.result.versionName + "_" + data.result.versionCode, false) + if (ignored && cancelable) { + return + } + val builder = SpannableStringBuilder() + if (data.result.versionType == 1) { + val betaTip = getString(R.string.tip_beta_version) + builder.append(betaTip, ForegroundColorSpan(resources.getColor(R.color.red, null)), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + builder.setSpan(StyleSpan(Typeface.BOLD), 0, betaTip.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + } + for (content in data.result.updateContent) { + builder.append(content) + builder.append("\n") + } + val dialogBuilder = DialogUtil.build(this@MainActivity) + .setTitle(getString(R.string.title_dialog_update, data.result.versionName)) + .setMessage(builder) + .setPositiveButton(R.string.button_go_to_download) { _: DialogInterface?, _: Int -> VersionUtil.showDownloadDialog(this@MainActivity, data.result) } + .setCancelable(cancelable) + if (cancelable) { + dialogBuilder.setNegativeButton(R.string.button_next_time, null) + dialogBuilder.setNeutralButton(R.string.button_ignore_this_version) { _: DialogInterface?, _: Int -> + SharedPreferencesUtil.get(this@MainActivity, SharedPreferencesUtil.SP_IGNORE_VERSIONS) + .edit() + .putBoolean(data.result.versionName + "_" + data.result.versionCode, true) + .apply() + } + } + showDialog(dialogBuilder.create()) + } + } + } + + override fun onFailure(code: Int, error: String) {} + }) + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.toolbar_menu, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + R.id.menu_sign -> { + TiebaUtil.startSign(this@MainActivity) + return true + } + R.id.action_search -> { + mSearchView!!.open(item) + return true + } + } + return super.onOptionsItemSelected(item) + } + + override fun onBackPressed() { + if (mSearchView!!.isOpen) { + mSearchView!!.close() + } else { + if (!HandleBackUtil.handleBackPress(this)) { + exit() + } + } + } + + @JvmOverloads + fun exit(isDouble: Boolean = true) { + if (!isDouble || System.currentTimeMillis() - lastTime < 2000) { + exitApplication() + } else { + lastTime = System.currentTimeMillis() + Toast.makeText(this, R.string.toast_double_key_exit, Toast.LENGTH_SHORT).show() + } + } + + override fun setTitle(newTitle: String) { + mToolbar!!.title = newTitle + } + + override fun onSearchItemClick(position: Int, content: CharSequence) { + startActivity(Intent(this@MainActivity, SearchActivity::class.java) + .putExtra(SearchActivity.EXTRA_KEYWORD, content.toString())) + SearchHistory(content.toString()) + .saveOrUpdate("content = ?", content.toString()) + refreshSearchView() + } + + private inner class NewMessageReceiver : BroadcastReceiver() { + @SuppressLint("RestrictedApi") + override fun onReceive(context: Context, intent: Intent) { + try { + val action = intent.action + if (action != null && action == NotifyJobService.ACTION_NEW_MESSAGE) { + val channel = intent.getStringExtra("channel") + val count = intent.getIntExtra("count", 0) + if (channel != null && channel == NotifyJobService.CHANNEL_TOTAL && badgeTextView != null) { + badgeTextView!!.text = count.toString() + if (count > 0) { + badgeTextView!!.visibility = View.VISIBLE + } + } + } + } catch (ignored: Exception) { + } + } + } + + private inner class AccountSwitchReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + val action = intent.action + if (action != null && action == AccountUtil.ACTION_SWITCH_ACCOUNT) { + if (mAdapter == null) { + return + } + val fragments = mAdapter!!.fragments + for (fragment in fragments) { + if (fragment != null) { + try { + fragment.onAccountSwitch() + } catch (e: Exception) { + e.printStackTrace() + } + } + } + } + } + } + + companion object { + const val TAG = "MainActivity" + const val SP_SHOULD_SHOW_SNACKBAR = "should_show_snackbar" + private val handler = Handler() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/fragments/SettingsFragment.java b/app/src/main/java/com/huanchengfly/tieba/post/fragments/SettingsFragment.java deleted file mode 100644 index 3edc87b0..00000000 --- a/app/src/main/java/com/huanchengfly/tieba/post/fragments/SettingsFragment.java +++ /dev/null @@ -1,234 +0,0 @@ -package com.huanchengfly.tieba.post.fragments; - - -import android.annotation.SuppressLint; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.view.View; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import androidx.preference.EditTextPreference; -import androidx.preference.ListPreference; -import androidx.preference.Preference; -import androidx.preference.SwitchPreference; - -import com.google.android.material.snackbar.Snackbar; -import com.huanchengfly.theme.utils.ThemeUtils; -import com.huanchengfly.tieba.api.LiteApi; -import com.huanchengfly.tieba.api.interfaces.CommonAPICallback; -import com.huanchengfly.tieba.api.models.NewUpdateBean; -import com.huanchengfly.tieba.post.R; -import com.huanchengfly.tieba.post.activities.BlockListActivity; -import com.huanchengfly.tieba.post.activities.LoginActivity; -import com.huanchengfly.tieba.post.components.prefs.TimePickerPreference; -import com.huanchengfly.tieba.post.models.database.Account; -import com.huanchengfly.tieba.post.models.database.Block; -import com.huanchengfly.tieba.post.utils.AccountUtil; -import com.huanchengfly.tieba.post.utils.DialogUtil; -import com.huanchengfly.tieba.post.utils.DisplayUtil; -import com.huanchengfly.tieba.post.utils.TiebaUtil; -import com.huanchengfly.tieba.post.utils.Util; -import com.huanchengfly.tieba.post.utils.VersionUtil; -import com.huanchengfly.utils.GlideCacheUtil; -import com.lapism.searchview.database.SearchHistoryTable; - -import java.util.ArrayList; -import java.util.List; - -public class SettingsFragment extends PreferencesFragment { - public static final String TAG = "SettingsFragment"; - - private Account loginInfo; - - public SettingsFragment() { - } - - @Override - public void onResume() { - super.onResume(); - refresh(); - } - - private void refresh() { - loginInfo = AccountUtil.getLoginInfo(getAttachContext()); - List accounts = AccountUtil.getAllAccounts(); - List usernameList = new ArrayList<>(); - List idList = new ArrayList<>(); - for (Account account : accounts) { - usernameList.add(account.getNameShow()); - idList.add(String.valueOf(account.getId())); - } - ListPreference accountsPreference = findPreference("switch_account"); - accountsPreference.setEntries(usernameList.toArray(new String[0])); - accountsPreference.setEntryValues(idList.toArray(new String[0])); - if (loginInfo != null) { - accountsPreference.setValue(String.valueOf(loginInfo.getId())); - accountsPreference.setSummary("已登录账号 " + loginInfo.getNameShow()); - } else { - accountsPreference.setSummary("未登录"); - } - } - - @SuppressLint("ApplySharedPref") - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - getPreferenceManager().setSharedPreferencesName("settings"); - addPreferencesFromResource(R.xml.preferences); - ListPreference accountsPreference = findPreference("switch_account"); - accountsPreference.setOnPreferenceChangeListener((preference, newValue) -> { - if (AccountUtil.switchUser(getAttachContext(), Integer.valueOf((String) newValue))) { - refresh(); - Toast.makeText(getAttachContext(), R.string.toast_switch_success, Toast.LENGTH_SHORT).show(); - } - return false; - }); - findPreference("copy_bduss").setOnPreferenceClickListener(preference -> { - Account account = AccountUtil.getLoginInfo(getAttachContext()); - if (account != null) { - TiebaUtil.copyText(getAttachContext(), account.getBduss()); - } - return true; - }); - findPreference("clear_search_history").setOnPreferenceClickListener(preference -> { - new SearchHistoryTable(getAttachContext()).clearDatabase(); - if (getView() != null) - Util.createSnackbar(getView(), R.string.toast_clear_success, Snackbar.LENGTH_SHORT).show(); - return true; - }); - findPreference("exit_account").setEnabled(AccountUtil.isLoggedIn(getAttachContext())); - findPreference("exit_account").setOnPreferenceClickListener(preference -> { - DialogUtil.build(getAttachContext()) - .setMessage(R.string.title_dialog_exit_account) - .setPositiveButton(R.string.button_sure_default, (dialog, which) -> { - AccountUtil.exit(getAttachContext()); - refresh(); - if (AccountUtil.getLoginInfo(getAttachContext()) == null) { - getAttachContext().startActivity(new Intent(getAttachContext(), LoginActivity.class)); - } - }) - .setNegativeButton(R.string.button_cancel, null) - .create() - .show(); - return true; - }); - findPreference("black_list").setOnPreferenceClickListener(preference -> { - startActivity(new Intent(getAttachContext(), BlockListActivity.class).putExtra("category", Block.CATEGORY_BLACK_LIST)); - return true; - }); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - findPreference("follow_system_night").setEnabled(true); - findPreference("follow_system_night").setSummary(null); - } else { - findPreference("follow_system_night").setEnabled(false); - findPreference("follow_system_night").setSummary(R.string.summary_follow_system_night_disabled); - } - findPreference("show_top_forum_in_normal_list").setOnPreferenceChangeListener((preference, newValue) -> { - preference.setSummary(R.string.summary_show_top_forum_in_normal_list_changed); - return true; - }); - findPreference("status_bar_darker").setOnPreferenceChangeListener((preference, newValue) -> { - preference.setSummary(R.string.summary_status_bar_darker_changed); - return true; - }); - findPreference("hideExplore").setOnPreferenceChangeListener((preference, newValue) -> { - preference.setSummary(R.string.summary_change_need_restart); - return true; - }); - findPreference("white_list").setOnPreferenceClickListener(preference -> { - startActivity(new Intent(getAttachContext(), BlockListActivity.class).putExtra("category", Block.CATEGORY_WHITE_LIST)); - return true; - }); - TimePickerPreference timePickerPreference = findPreference("auto_sign_time"); - timePickerPreference.setOnPreferenceChangeListener((preference, newValue) -> { - preference.setSummary(getAttachContext().getString(R.string.summary_auto_sign_time, (String) newValue)); - return true; - }); - timePickerPreference.setSummary(getAttachContext().getString(R.string.summary_auto_sign_time, getPreferenceManager().getSharedPreferences().getString("auto_sign_time", "09:00"))); - Preference clearCache = findPreference("clear_cache"); - clearCache.setSummary(getAttachContext().getString(R.string.tip_cache, GlideCacheUtil.getInstance().getCacheSize(getAttachContext()))); - clearCache.setOnPreferenceClickListener(preference -> { - GlideCacheUtil.getInstance().clearImageAllCache(getAttachContext()); - if (getView() != null) - Util.createSnackbar(getView(), R.string.toast_clear_cache_success, Snackbar.LENGTH_SHORT).show(); - preference.setSummary(getAttachContext().getString(R.string.tip_cache, "0.0B")); - return true; - }); - EditTextPreference littleTaliPreference = findPreference("little_tail"); - String littleTali = getPreferenceManager().getSharedPreferences().getString("little_tail", ""); - if (littleTali.isEmpty()) { - littleTaliPreference.setSummary(R.string.tip_no_little_tail); - } else { - littleTaliPreference.setSummary(littleTali); - littleTaliPreference.setText(littleTali); - } - littleTaliPreference.setOnPreferenceChangeListener((preference, value) -> { - if (value instanceof String) { - String tail = (String) value; - if (tail.isEmpty()) { - littleTaliPreference.setSummary(R.string.tip_no_little_tail); - } else { - littleTaliPreference.setSummary(tail); - littleTaliPreference.setText(tail); - } - } - return true; - }); - Preference aboutPreference = findPreference("about"); - LiteApi.getInstance().newCheckUpdate(new CommonAPICallback() { - @Override - public void onSuccess(NewUpdateBean data) { - if (data.isHasUpdate()) { - aboutPreference.setSummary(getAttachContext().getString(R.string.tip_new_version, data.getResult().getVersionName())); - } - } - - @Override - public void onFailure(int code, String error) { - } - }); - SwitchPreference useCustomTabs = findPreference("use_custom_tabs"); - useCustomTabs.setEnabled(!getPreferenceManager().getSharedPreferences().getBoolean("use_webview", true)); - findPreference("use_webview").setOnPreferenceChangeListener((preference, newValue) -> { - useCustomTabs.setEnabled(!(boolean) newValue); - return true; - }); - initListPreference("dark_theme", "dark"); - aboutPreference.setSummary(getString(R.string.tip_about, VersionUtil.getVersionName(getAttachContext()))); - refresh(); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - setDivider(ThemeUtils.tintDrawable(ContextCompat.getDrawable(getAttachContext(), R.drawable.drawable_divider_8dp), ThemeUtils.getColorByAttr(getAttachContext(), R.attr.colorDivider))); - setDividerHeight(DisplayUtil.dp2px(getAttachContext(), 8)); - } - - private void initSwitchPreference(String key) { - initSwitchPreference(key, false); - } - - private void initSwitchPreference(SwitchPreference switchPreference) { - initSwitchPreference(switchPreference, false); - } - - private void initSwitchPreference(String key, boolean defValue) { - SwitchPreference switchPreference = findPreference(key); - initSwitchPreference(switchPreference, defValue); - } - - private void initSwitchPreference(SwitchPreference switchPreference, boolean defValue) { - boolean value = getPreferenceManager().getSharedPreferences().getBoolean(switchPreference.getKey(), defValue); - switchPreference.setChecked(value); - } - - private void initListPreference(String key, String defValue) { - ListPreference listPreference = findPreference(key); - String value = getPreferenceManager().getSharedPreferences().getString(key, defValue); - listPreference.setValue(value); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/fragments/SettingsFragment.kt b/app/src/main/java/com/huanchengfly/tieba/post/fragments/SettingsFragment.kt new file mode 100644 index 00000000..54ed4504 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/fragments/SettingsFragment.kt @@ -0,0 +1,206 @@ +package com.huanchengfly.tieba.post.fragments + +import android.annotation.SuppressLint +import android.content.DialogInterface +import android.content.Intent +import android.os.Build +import android.os.Bundle +import android.view.View +import android.widget.Toast +import androidx.core.content.ContextCompat +import androidx.preference.EditTextPreference +import androidx.preference.ListPreference +import androidx.preference.Preference +import androidx.preference.SwitchPreference +import com.google.android.material.snackbar.Snackbar +import com.huanchengfly.theme.utils.ThemeUtils +import com.huanchengfly.tieba.api.LiteApi.Companion.instance +import com.huanchengfly.tieba.api.interfaces.CommonAPICallback +import com.huanchengfly.tieba.api.models.NewUpdateBean +import com.huanchengfly.tieba.post.R +import com.huanchengfly.tieba.post.activities.BlockListActivity +import com.huanchengfly.tieba.post.activities.LoginActivity +import com.huanchengfly.tieba.post.components.prefs.TimePickerPreference +import com.huanchengfly.tieba.post.models.database.Account +import com.huanchengfly.tieba.post.models.database.Block +import com.huanchengfly.tieba.post.utils.* +import com.huanchengfly.utils.GlideCacheUtil +import com.lapism.searchview.database.SearchHistoryTable +import java.util.* + +class SettingsFragment : PreferencesFragment() { + private var loginInfo: Account? = null + override fun onResume() { + super.onResume() + refresh() + } + + private fun refresh() { + loginInfo = AccountUtil.getLoginInfo(attachContext) + val accounts = AccountUtil.getAllAccounts() + val usernameList: MutableList = ArrayList() + val idList: MutableList = ArrayList() + for (account in accounts) { + usernameList.add(account.nameShow) + idList.add(account.id.toString()) + } + val accountsPreference = findPreference("switch_account") + accountsPreference!!.entries = usernameList.toTypedArray() + accountsPreference.entryValues = idList.toTypedArray() + if (loginInfo != null) { + accountsPreference.value = loginInfo!!.id.toString() + accountsPreference.summary = "已登录账号 " + loginInfo!!.nameShow + } else { + accountsPreference.summary = "未登录" + } + } + + @SuppressLint("ApplySharedPref") + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + preferenceManager.sharedPreferencesName = "settings" + addPreferencesFromResource(R.xml.preferences) + val accountsPreference = findPreference("switch_account") + accountsPreference!!.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any? -> + if (AccountUtil.switchUser(attachContext, Integer.valueOf((newValue as String?)!!))) { + refresh() + Toast.makeText(attachContext, R.string.toast_switch_success, Toast.LENGTH_SHORT).show() + } + false + } + findPreference("copy_bduss")!!.onPreferenceClickListener = Preference.OnPreferenceClickListener { + val account = AccountUtil.getLoginInfo(attachContext) + if (account != null) { + TiebaUtil.copyText(attachContext, account.bduss) + } + true + } + findPreference("clear_search_history")!!.onPreferenceClickListener = Preference.OnPreferenceClickListener { + SearchHistoryTable(attachContext).clearDatabase() + if (view != null) Util.createSnackbar(view!!, R.string.toast_clear_success, Snackbar.LENGTH_SHORT).show() + true + } + findPreference("exit_account")!!.isEnabled = AccountUtil.isLoggedIn(attachContext) + findPreference("exit_account")!!.onPreferenceClickListener = Preference.OnPreferenceClickListener { + DialogUtil.build(attachContext) + .setMessage(R.string.title_dialog_exit_account) + .setPositiveButton(R.string.button_sure_default) { _: DialogInterface?, _: Int -> + AccountUtil.exit(attachContext) + refresh() + if (AccountUtil.getLoginInfo(attachContext) == null) { + attachContext.startActivity(Intent(attachContext, LoginActivity::class.java)) + } + } + .setNegativeButton(R.string.button_cancel, null) + .create() + .show() + true + } + findPreference("black_list")!!.onPreferenceClickListener = Preference.OnPreferenceClickListener { + startActivity(Intent(attachContext, BlockListActivity::class.java).putExtra("category", Block.CATEGORY_BLACK_LIST)) + true + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + findPreference("follow_system_night")!!.isEnabled = true + findPreference("follow_system_night")!!.summary = null + } else { + findPreference("follow_system_night")!!.isEnabled = false + findPreference("follow_system_night")!!.setSummary(R.string.summary_follow_system_night_disabled) + } + findPreference("show_top_forum_in_normal_list")!!.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference: Preference, _: Any? -> + preference.setSummary(R.string.summary_show_top_forum_in_normal_list_changed) + true + } + findPreference("status_bar_darker")!!.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference: Preference, _: Any? -> + preference.setSummary(R.string.summary_status_bar_darker_changed) + true + } + findPreference("hideExplore")!!.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference: Preference, _: Any? -> + preference.setSummary(R.string.summary_change_need_restart) + true + } + findPreference("white_list")!!.onPreferenceClickListener = Preference.OnPreferenceClickListener { + startActivity(Intent(attachContext, BlockListActivity::class.java).putExtra("category", Block.CATEGORY_WHITE_LIST)) + true + } + val timePickerPreference = findPreference("auto_sign_time") + timePickerPreference!!.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference: Preference, newValue: Any? -> + preference.summary = attachContext.getString(R.string.summary_auto_sign_time, newValue as String?) + true + } + timePickerPreference.summary = attachContext.getString(R.string.summary_auto_sign_time, preferenceManager.sharedPreferences.getString("auto_sign_time", "09:00")) + val clearCache = findPreference("clear_cache") + clearCache!!.summary = attachContext.getString(R.string.tip_cache, GlideCacheUtil.getInstance().getCacheSize(attachContext)) + clearCache.onPreferenceClickListener = Preference.OnPreferenceClickListener { preference: Preference -> + GlideCacheUtil.getInstance().clearImageAllCache(attachContext) + if (view != null) Util.createSnackbar(view!!, R.string.toast_clear_cache_success, Snackbar.LENGTH_SHORT).show() + preference.summary = attachContext.getString(R.string.tip_cache, "0.0B") + true + } + val littleTaliPreference = findPreference("little_tail") + val littleTali = preferenceManager.sharedPreferences.getString("little_tail", "") + if (littleTali!!.isEmpty()) { + littleTaliPreference!!.setSummary(R.string.tip_no_little_tail) + } else { + littleTaliPreference!!.summary = littleTali + littleTaliPreference.text = littleTali + } + littleTaliPreference.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _: Preference?, value: Any? -> + if (value is String) { + if (value.isEmpty()) { + littleTaliPreference.setSummary(R.string.tip_no_little_tail) + } else { + littleTaliPreference.summary = value + littleTaliPreference.text = value + } + } + true + } + val aboutPreference = findPreference("about") + instance!!.newCheckUpdate(object : CommonAPICallback { + override fun onSuccess(data: NewUpdateBean?) { + if (data != null) { + if (data.isHasUpdate) { + aboutPreference!!.summary = attachContext.getString(R.string.tip_new_version, data.result.versionName) + } + } + } + + override fun onFailure(code: Int, error: String) {} + }) + val useCustomTabs = findPreference("use_custom_tabs") + useCustomTabs!!.isEnabled = !preferenceManager.sharedPreferences.getBoolean("use_webview", true) + findPreference("use_webview")!!.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any? -> + useCustomTabs.isEnabled != newValue as Boolean + true + } + initListPreference("dark_theme", "dark") + aboutPreference!!.summary = getString(R.string.tip_about, VersionUtil.getVersionName(attachContext)) + refresh() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setDivider(ThemeUtils.tintDrawable(ContextCompat.getDrawable(attachContext, R.drawable.drawable_divider_8dp), ThemeUtils.getColorByAttr(attachContext, R.attr.colorDivider))) + setDividerHeight(DisplayUtil.dp2px(attachContext, 8f)) + } + + private fun initSwitchPreference(key: String, defValue: Boolean = false) { + val switchPreference = findPreference(key) + initSwitchPreference(switchPreference, defValue) + } + + private fun initSwitchPreference(switchPreference: SwitchPreference?, defValue: Boolean = false) { + val value = preferenceManager.sharedPreferences.getBoolean(switchPreference!!.key, defValue) + switchPreference.isChecked = value + } + + private fun initListPreference(key: String, defValue: String) { + val listPreference = findPreference(key) + val value = preferenceManager.sharedPreferences.getString(key, defValue) + listPreference!!.value = value + } + + companion object { + const val TAG = "SettingsFragment" + } +} \ No newline at end of file diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 4112319b..219f7b28 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -1,5 +1,4 @@ - - + + android:title="@string/title_switch_account" /> - + android:title="@string/title_new_account" + android:summary="@string/tip_account_error"> + - + android:summary="@string/summary_copy_bduss" /> - + - + - + - + + android:title="@string/title_auto_sign" /> + android:summary="@string/tip_auto_sign" /> - + + android:summary="@string/tip_check_beta_update" /> + android:summaryOff="@string/tip_use_webview" /> + android:summaryOff="@string/tip_use_custom_tab" /> - + + android:targetPackage="top.goforce.tieba.post" /> + android:targetPackage="top.goforce.tieba.post" /> + android:targetPackage="top.goforce.tieba.post" /> \ No newline at end of file