diff --git a/android/app/src/main/java/com/hyzq/boss/MainActivity.java b/android/app/src/main/java/com/hyzq/boss/MainActivity.java index bc683ad..a0ecd4e 100644 --- a/android/app/src/main/java/com/hyzq/boss/MainActivity.java +++ b/android/app/src/main/java/com/hyzq/boss/MainActivity.java @@ -22,6 +22,9 @@ import java.util.concurrent.Executors; public class MainActivity extends AppCompatActivity { public static final String EXTRA_INITIAL_TAB = "initial_tab"; + private static final String UI_PREFS = "boss_native_client"; + private static final String KEY_LAST_ROOT_TAB = "last_root_tab"; + private static final long ROOT_BACK_EXIT_WINDOW_MS = 1_500L; private final ExecutorService executor = Executors.newSingleThreadExecutor(); @@ -45,8 +48,9 @@ public class MainActivity extends AppCompatActivity { private String activeTab = "conversations"; private String preferredEntryTab = "conversations"; - private boolean explicitTabRequest = false; + private @Nullable String requestedInitialTab; private boolean userSelectedTab = false; + private long lastRootBackPressedAt = 0L; private @Nullable JSONObject sessionData; private @Nullable JSONObject otaData; private @Nullable JSONArray conversationsData; @@ -78,10 +82,17 @@ public class MainActivity extends AppCompatActivity { public void onBackPressed() { if (contentPanel.getVisibility() == View.VISIBLE && !"conversations".equals(activeTab)) { setActiveTab("conversations", false); + persistLastRootTab("conversations"); return; } if (contentPanel.getVisibility() == View.VISIBLE) { - moveTaskToBack(true); + long now = System.currentTimeMillis(); + if (now - lastRootBackPressedAt < ROOT_BACK_EXIT_WINDOW_MS) { + moveTaskToBack(true); + return; + } + lastRootBackPressedAt = now; + showMessage("再按一次返回,应用进入后台"); return; } super.onBackPressed(); @@ -126,12 +137,12 @@ public class MainActivity extends AppCompatActivity { } private void applyInitialTab(@Nullable Intent intent) { - explicitTabRequest = false; + requestedInitialTab = null; String requested = intent == null ? null : intent.getStringExtra(EXTRA_INITIAL_TAB); if ("devices".equals(requested) || "me".equals(requested) || "conversations".equals(requested)) { - activeTab = requested; - explicitTabRequest = true; + requestedInitialTab = requested; } + activeTab = RootTabMemory.resolveInitialTab(requestedInitialTab, readLastRootTab(), preferredEntryTab); } private void bootstrapSession() { @@ -261,18 +272,18 @@ public class MainActivity extends AppCompatActivity { activeTab = tab; if (fromUser) { userSelectedTab = true; + persistLastRootTab(tab); } + lastRootBackPressedAt = 0L; updateTabStyles(); renderCurrentTab(); } private void maybeApplyPreferredEntry() { - if (explicitTabRequest || userSelectedTab) { + if (userSelectedTab) { return; } - if ("devices".equals(preferredEntryTab) || "me".equals(preferredEntryTab) || "conversations".equals(preferredEntryTab)) { - activeTab = preferredEntryTab; - } + activeTab = RootTabMemory.resolveInitialTab(requestedInitialTab, readLastRootTab(), preferredEntryTab); } private void renderCurrentTab() { @@ -495,4 +506,16 @@ public class MainActivity extends AppCompatActivity { } return null; } + + private void persistLastRootTab(String tab) { + getSharedPreferences(UI_PREFS, MODE_PRIVATE) + .edit() + .putString(KEY_LAST_ROOT_TAB, tab) + .apply(); + } + + private @Nullable String readLastRootTab() { + return getSharedPreferences(UI_PREFS, MODE_PRIVATE) + .getString(KEY_LAST_ROOT_TAB, null); + } } diff --git a/android/app/src/main/java/com/hyzq/boss/RootTabMemory.java b/android/app/src/main/java/com/hyzq/boss/RootTabMemory.java new file mode 100644 index 0000000..bb400c1 --- /dev/null +++ b/android/app/src/main/java/com/hyzq/boss/RootTabMemory.java @@ -0,0 +1,28 @@ +package com.hyzq.boss; + +public final class RootTabMemory { + private RootTabMemory() {} + + public static String resolveInitialTab(String explicitTab, String storedTab, String preferredTab) { + String explicit = normalize(explicitTab); + if (explicit != null) { + return explicit; + } + String stored = normalize(storedTab); + if (stored != null) { + return stored; + } + String preferred = normalize(preferredTab); + if (preferred != null) { + return preferred; + } + return "conversations"; + } + + private static String normalize(String tab) { + if ("conversations".equals(tab) || "devices".equals(tab) || "me".equals(tab)) { + return tab; + } + return null; + } +} diff --git a/android/app/src/test/java/com/hyzq/boss/RootTabMemoryTest.java b/android/app/src/test/java/com/hyzq/boss/RootTabMemoryTest.java new file mode 100644 index 0000000..8eb42de --- /dev/null +++ b/android/app/src/test/java/com/hyzq/boss/RootTabMemoryTest.java @@ -0,0 +1,27 @@ +package com.hyzq.boss; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class RootTabMemoryTest { + @Test + public void resolveInitialTab_prefersExplicitTab() { + assertEquals("devices", RootTabMemory.resolveInitialTab("devices", "me", "conversations")); + } + + @Test + public void resolveInitialTab_fallsBackToStoredTab() { + assertEquals("me", RootTabMemory.resolveInitialTab(null, "me", "devices")); + } + + @Test + public void resolveInitialTab_usesPreferredEntryBeforeDefault() { + assertEquals("devices", RootTabMemory.resolveInitialTab(null, null, "devices")); + } + + @Test + public void resolveInitialTab_defaultsToConversations() { + assertEquals("conversations", RootTabMemory.resolveInitialTab(null, null, null)); + } +}