diff --git a/app/src/main/java/com/hippo/ehviewer/Settings.java b/app/src/main/java/com/hippo/ehviewer/Settings.java index ba9278df9..2d05eeeb3 100755 --- a/app/src/main/java/com/hippo/ehviewer/Settings.java +++ b/app/src/main/java/com/hippo/ehviewer/Settings.java @@ -131,6 +131,8 @@ public class Settings { private static final String DEFAULT_EXCLUDED_LANGUAGES = null; private static final String KEY_METERED_NETWORK_WARNING = "cellular_network_warning"; private static final boolean DEFAULT_METERED_NETWORK_WARNING = false; + private static final String KEY_APP_LINK_VERIFY_TIP = "app_link_verify_tip"; + private static final boolean DEFAULT_APP_LINK_VERIFY_TIP = false; private static final String KEY_NIGHT_MODE = "night_mode"; private static final String DEFAULT_NIGHT_MODE = "-1"; private static final String KEY_E_INK_MODE = "e_ink_mode_2"; @@ -604,6 +606,14 @@ public class Settings { return getBoolean(KEY_METERED_NETWORK_WARNING, DEFAULT_METERED_NETWORK_WARNING); } + public static boolean getAppLinkVerifyTip() { + return getBoolean(KEY_APP_LINK_VERIFY_TIP, DEFAULT_APP_LINK_VERIFY_TIP); + } + + public static void putAppLinkVerifyTip(boolean value) { + putBoolean(KEY_APP_LINK_VERIFY_TIP, value); + } + public static int getScreenRotation() { return getIntFromStr(KEY_SCREEN_ROTATION, DEFAULT_SCREEN_ROTATION); } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java index 6c3e5d16d..96fe366ec 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java @@ -19,6 +19,9 @@ package com.hippo.ehviewer.ui; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.verify.domain.DomainVerificationManager; +import android.content.pm.verify.domain.DomainVerificationUserState; import android.content.res.Configuration; import android.graphics.Bitmap; import android.net.ConnectivityManager; @@ -38,6 +41,7 @@ import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.IdRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatDelegate; @@ -91,6 +95,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.Map; import rikka.material.app.DayNightDelegate; @@ -347,6 +352,15 @@ public final class MainActivity extends StageActivity if (Settings.getMeteredNetworkWarning()) { checkMeteredNetwork(); } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + if (!Settings.getAppLinkVerifyTip()) { + try { + checkAppLinkVerify(); + } catch (PackageManager.NameNotFoundException ignored) { + + } + } + } } else { onRestore(savedInstanceState); } @@ -354,6 +368,41 @@ public final class MainActivity extends StageActivity EhTagDatabase.update(this); } + + @RequiresApi(api = Build.VERSION_CODES.S) + private void checkAppLinkVerify() throws PackageManager.NameNotFoundException { + DomainVerificationManager manager = getSystemService(DomainVerificationManager.class); + DomainVerificationUserState userState = manager.getDomainVerificationUserState(getPackageName()); + + if (userState == null) { + return; + } + + boolean hasUnverified = false; + Map hostToStateMap = userState.getHostToStateMap(); + for (String key : hostToStateMap.keySet()) { + Integer stateValue = hostToStateMap.get(key); + if (stateValue == null || stateValue == DomainVerificationUserState.DOMAIN_STATE_VERIFIED || stateValue == DomainVerificationUserState.DOMAIN_STATE_SELECTED) { + continue; + } + hasUnverified = true; + break; + } + if (hasUnverified) { + new AlertDialog.Builder(this) + .setTitle(R.string.app_link_not_verified_title) + .setMessage(R.string.app_link_not_verified_message) + .setPositiveButton(R.string.open_settings, (dialogInterface, i) -> { + Intent intent = new Intent(android.provider.Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS, + Uri.parse("package:" + getPackageName())); + startActivity(intent); + }) + .setNegativeButton(android.R.string.cancel, null) + .setNeutralButton(R.string.dont_show_again, (dialogInterface, i) -> Settings.putAppLinkVerifyTip(true)) + .show(); + } + } + private void checkDownloadLocation() { UniFile uniFile = Settings.getDownloadLocation(); // null == uniFile for first start diff --git a/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java b/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java index 08eddf209..29533291d 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java @@ -18,7 +18,10 @@ package com.hippo.ehviewer.ui.fragment; import android.app.Activity; import android.content.Intent; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.provider.Settings; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; @@ -59,6 +62,7 @@ public class AdvancedFragment extends BasePreferenceFragment { private static final String KEY_APP_LANGUAGE = "app_language"; private static final String KEY_IMPORT_DATA = "import_data"; private static final String KEY_EXPORT_DATA = "export_data"; + private static final String KEY_OPEN_BY_DEFAULT = "open_by_default"; ActivityResultLauncher exportLauncher = registerForActivityResult( new ActivityResultContracts.CreateDocument(), @@ -225,6 +229,13 @@ public class AdvancedFragment extends BasePreferenceFragment { Preference appLanguage = findPreference(KEY_APP_LANGUAGE); Preference importData = findPreference(KEY_IMPORT_DATA); Preference exportData = findPreference(KEY_EXPORT_DATA); + Preference openByDefault = findPreference(KEY_OPEN_BY_DEFAULT); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + openByDefault.setVisible(false); + } else { + openByDefault.setOnPreferenceClickListener(this); + } dumpLogcat.setOnPreferenceClickListener(this); clearMemoryCache.setOnPreferenceClickListener(this); @@ -265,6 +276,11 @@ public class AdvancedFragment extends BasePreferenceFragment { showTip(R.string.error_cant_find_activity, BaseScene.LENGTH_SHORT); } return true; + } else if (KEY_OPEN_BY_DEFAULT.equals(key)) { + Intent intent = new Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS, + Uri.parse("package:" + requireContext().getPackageName())); + startActivity(intent); + return true; } return false; } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 52446b76f..74d178e8e 100755 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -754,4 +754,9 @@ 复制翻译 恢复默认路径 选择新路径 + 不再显示 + 打开设置 + 对于 Android 12 及更新的版本,您需要手动添加链接到已验证链接才能在 EhViewer 中打开 E-Hentai 链接。 + 应用链接未验证 + 默认打开 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1ae7ebe1e..9c2d81512 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -818,4 +818,9 @@ Copy translation Reset to default Pick a new location + Don\'t show again + Open settings + For Android 12 and newer, you need to manually add link to verified links in order to open E-Hentai links in EhViewer. + App links not verified + Open by default diff --git a/app/src/main/res/xml/advanced_settings.xml b/app/src/main/res/xml/advanced_settings.xml index 85beecddb..4485f8ed3 100644 --- a/app/src/main/res/xml/advanced_settings.xml +++ b/app/src/main/res/xml/advanced_settings.xml @@ -112,4 +112,9 @@ android:title="@string/settings_advanced_import_data" app:iconSpaceReserved="false" /> + +