From 1e907b552d0140b226e5506d199d8e38308a836f Mon Sep 17 00:00:00 2001 From: okjack Date: Mon, 20 May 2024 15:44:15 +0800 Subject: [PATCH 1/2] okhttp dns ipv4 priority --- .../java/com/github/catvod/net/OkDns.java | 25 +++++++++++++++++++ .../java/com/github/catvod/net/OkHttp.java | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 catvod/src/main/java/com/github/catvod/net/OkDns.java diff --git a/catvod/src/main/java/com/github/catvod/net/OkDns.java b/catvod/src/main/java/com/github/catvod/net/OkDns.java new file mode 100644 index 000000000..ad995882d --- /dev/null +++ b/catvod/src/main/java/com/github/catvod/net/OkDns.java @@ -0,0 +1,25 @@ +package com.github.catvod.net; + +import androidx.annotation.NonNull; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; + +import okhttp3.Dns; + +public class OkDns implements Dns { + + @NonNull + @Override + public List lookup(@NonNull String hostname) throws UnknownHostException { + List items = new ArrayList<>(); + for (InetAddress address : InetAddress.getAllByName(hostname)) { + if (address instanceof Inet4Address) items.add(0, address); + else items.add(address); + } + return items; + } +} diff --git a/catvod/src/main/java/com/github/catvod/net/OkHttp.java b/catvod/src/main/java/com/github/catvod/net/OkHttp.java index d19005eae..d311c33ca 100644 --- a/catvod/src/main/java/com/github/catvod/net/OkHttp.java +++ b/catvod/src/main/java/com/github/catvod/net/OkHttp.java @@ -49,7 +49,7 @@ public class OkHttp { } public static Dns dns() { - return get().dns != null ? get().dns : Dns.SYSTEM; + return get().dns != null ? get().dns : new OkDns(); } public void setDoh(Doh doh) { From e72bb4809ce07c2eee0fa08edbc20e649db7fb4c Mon Sep 17 00:00:00 2001 From: okjack Date: Mon, 20 May 2024 16:05:35 +0800 Subject: [PATCH 2/2] restore --- .../android/tv/ui/activity/HomeActivity.java | 16 +---- .../tv/ui/activity/SettingActivity.java | 47 ++++++++++++--- .../android/tv/ui/dialog/RestoreDialog.java | 56 +++++++----------- .../leanback/res/layout/activity_setting.xml | 59 +++++++++++++------ .../java/com/fongmi/android/tv/Setting.java | 8 +-- .../com/fongmi/android/tv/db/AppDatabase.java | 39 ++++++------ .../android/tv/impl/RestoreCallback.java | 6 +- .../com/fongmi/android/tv/utils/FileUtil.java | 32 ++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 8 ++- app/src/main/res/values-zh-rTW/strings.xml | 8 ++- app/src/main/res/values/strings.xml | 8 ++- .../android/tv/ui/activity/MainActivity.java | 19 ------ .../tv/ui/fragment/SettingFragment.java | 44 +++++++++++--- .../mobile/res/layout/fragment_setting.xml | 18 ++++++ .../java/com/github/catvod/utils/Path.java | 4 ++ 15 files changed, 242 insertions(+), 130 deletions(-) diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java index 00e6753f4..01325bdbc 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java @@ -47,7 +47,6 @@ import com.fongmi.android.tv.event.RefreshEvent; import com.fongmi.android.tv.event.ServerEvent; import com.fongmi.android.tv.impl.Callback; import com.fongmi.android.tv.impl.ConfigCallback; -import com.fongmi.android.tv.impl.RestoreCallback; import com.fongmi.android.tv.model.SiteViewModel; import com.fongmi.android.tv.player.Source; import com.fongmi.android.tv.server.Server; @@ -55,7 +54,6 @@ import com.fongmi.android.tv.ui.base.BaseActivity; import com.fongmi.android.tv.ui.custom.CustomTitleView; import com.fongmi.android.tv.ui.dialog.HistoryDialog; import com.fongmi.android.tv.ui.dialog.MenuDialog; -import com.fongmi.android.tv.ui.dialog.RestoreDialog; import com.fongmi.android.tv.ui.dialog.SiteDialog; import com.fongmi.android.tv.ui.fragment.HomeFragment; import com.fongmi.android.tv.ui.fragment.VodFragment; @@ -79,7 +77,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -public class HomeActivity extends BaseActivity implements CustomTitleView.Listener, RestoreCallback, TypePresenter.OnClickListener, ConfigCallback { +public class HomeActivity extends BaseActivity implements CustomTitleView.Listener, TypePresenter.OnClickListener, ConfigCallback { public ActivityHomeBinding mBinding; private ArrayObjectAdapter mAdapter; @@ -331,7 +329,6 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen @Override public void error(String msg) { - if (TextUtils.isEmpty(msg) && AppDatabase.getBackup().exists()) RestoreDialog.create(getActivity()).show(); if (getHomeFragment().init) getHomeFragment().mBinding.progressLayout.showContent(); else App.post(() -> getHomeFragment().mBinding.progressLayout.showContent(), 1000); mResult = Result.empty(); @@ -341,17 +338,6 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen }; } - @Override - public void onRestore() { - PermissionX.init(this).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> AppDatabase.restore(new Callback() { - @Override - public void success() { - if (allGranted && getHomeFragment().init) getHomeFragment().mBinding.progressLayout.showProgress(); - if (allGranted) initConfig(); - } - })); - } - private void load(Config config, String success) { switch (config.getType()) { case 0: diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingActivity.java index a99f141b1..7f150f942 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingActivity.java @@ -3,11 +3,14 @@ package com.fongmi.android.tv.ui.activity; import android.Manifest; import android.app.Activity; import android.content.Intent; +import android.util.Base64; import android.view.View; import androidx.viewbinding.ViewBinding; +import com.fongmi.android.tv.App; import com.fongmi.android.tv.BuildConfig; +import com.fongmi.android.tv.R; import com.fongmi.android.tv.Setting; import com.fongmi.android.tv.Updater; import com.fongmi.android.tv.api.config.LiveConfig; @@ -24,6 +27,7 @@ import com.fongmi.android.tv.impl.ConfigCallback; import com.fongmi.android.tv.impl.DohCallback; import com.fongmi.android.tv.impl.LiveCallback; import com.fongmi.android.tv.impl.ProxyCallback; +import com.fongmi.android.tv.impl.RestoreCallback; import com.fongmi.android.tv.impl.SiteCallback; import com.fongmi.android.tv.player.ExoUtil; import com.fongmi.android.tv.ui.base.BaseActivity; @@ -32,20 +36,24 @@ import com.fongmi.android.tv.ui.dialog.DohDialog; import com.fongmi.android.tv.ui.dialog.HistoryDialog; import com.fongmi.android.tv.ui.dialog.LiveDialog; import com.fongmi.android.tv.ui.dialog.ProxyDialog; +import com.fongmi.android.tv.ui.dialog.RestoreDialog; import com.fongmi.android.tv.ui.dialog.SiteDialog; import com.fongmi.android.tv.utils.FileUtil; import com.fongmi.android.tv.utils.Notify; +import com.fongmi.android.tv.utils.ResUtil; import com.fongmi.android.tv.utils.UrlUtil; import com.github.catvod.bean.Doh; import com.github.catvod.net.OkHttp; import com.permissionx.guolindev.PermissionX; +import java.io.File; import java.util.ArrayList; import java.util.List; -public class SettingActivity extends BaseActivity implements ConfigCallback, SiteCallback, LiveCallback, DohCallback, ProxyCallback { +public class SettingActivity extends BaseActivity implements RestoreCallback, ConfigCallback, SiteCallback, LiveCallback, DohCallback, ProxyCallback { private ActivitySettingBinding mBinding; + private String[] backup; private int type; public static void start(Activity activity) { @@ -73,10 +81,10 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit mBinding.vodUrl.setText(VodConfig.getDesc()); mBinding.liveUrl.setText(LiveConfig.getDesc()); mBinding.wallUrl.setText(WallConfig.getDesc()); - mBinding.backupText.setText(AppDatabase.getDate()); mBinding.dohText.setText(getDohList()[getDohIndex()]); mBinding.versionText.setText(BuildConfig.VERSION_NAME); mBinding.proxyText.setText(UrlUtil.scheme(Setting.getProxy())); + mBinding.backupText.setText((backup = ResUtil.getStringArray(R.array.select_backup))[Setting.getBackupMode()]); mBinding.aboutText.setText(BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_api + "-" + BuildConfig.FLAVOR_abi); setCacheText(); } @@ -99,6 +107,7 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit mBinding.cache.setOnClickListener(this::onCache); mBinding.cache.setOnLongClickListener(this::onCacheLongClick); mBinding.backup.setOnClickListener(this::onBackup); + mBinding.restore.setOnClickListener(this::onRestore); mBinding.player.setOnClickListener(this::onPlayer); mBinding.danmu.setOnClickListener(this::onDanmu); mBinding.version.setOnClickListener(this::onVersion); @@ -107,7 +116,7 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit mBinding.live.setOnLongClickListener(this::onLiveEdit); mBinding.liveHome.setOnClickListener(this::onLiveHome); mBinding.wall.setOnLongClickListener(this::onWallEdit); - mBinding.backup.setOnLongClickListener(this::onBackupAuto); + mBinding.backup.setOnLongClickListener(this::onBackupMode); mBinding.vodHistory.setOnClickListener(this::onVodHistory); mBinding.version.setOnLongClickListener(this::onVersionDev); mBinding.liveHistory.setOnClickListener(this::onLiveHistory); @@ -334,18 +343,42 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit return true; } + @Override + public void onRestore(File file) { + PermissionX.init(this).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> AppDatabase.restore(file, new Callback() { + @Override + public void success() { + if (allGranted) { + Notify.progress(getActivity()); + App.post(() -> initConfig(), 3000); + } + } + })); + } + + private void onRestore(View view) { + RestoreDialog.create().callback(this).show(getActivity()); + } + + private void initConfig() { + WallConfig.get().init(); + LiveConfig.get().init().load(); + VodConfig.get().init().load(getCallback()); + } + private void onBackup(View view) { PermissionX.init(this).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> AppDatabase.backup(new Callback() { @Override public void success() { - mBinding.backupText.setText(AppDatabase.getDate()); + Notify.show(R.string.backed); } })); } - private boolean onBackupAuto(View view) { - Setting.putBackupAuto(!Setting.isBackupAuto()); - mBinding.backupText.setText(AppDatabase.getDate()); + private boolean onBackupMode(View view) { + int index = Setting.getBackupMode(); + Setting.putBackupMode(index = index == backup.length - 1 ? 0 : ++index); + mBinding.backupText.setText(backup[index]); return true; } diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/dialog/RestoreDialog.java b/app/src/leanback/java/com/fongmi/android/tv/ui/dialog/RestoreDialog.java index 449009653..c0bf26fa1 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/dialog/RestoreDialog.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/dialog/RestoreDialog.java @@ -1,52 +1,40 @@ package com.fongmi.android.tv.ui.dialog; import android.app.Activity; -import android.view.LayoutInflater; -import android.view.View; - -import androidx.appcompat.app.AlertDialog; - -import com.fongmi.android.tv.databinding.DialogRestoreBinding; import com.fongmi.android.tv.impl.RestoreCallback; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.github.catvod.utils.Path; +import com.obsez.android.lib.filechooser.ChooserDialog; + +import java.io.File; public class RestoreDialog { - private final DialogRestoreBinding binding; - private final RestoreCallback callback; - private final AlertDialog dialog; + private ChooserDialog dialog; - public static RestoreDialog create(Activity activity) { - return new RestoreDialog(activity); - } + private RestoreCallback callback; - public RestoreDialog(Activity activity) { - this.callback = (RestoreCallback) activity; - this.binding = DialogRestoreBinding.inflate(LayoutInflater.from(activity)); - this.dialog = new MaterialAlertDialogBuilder(activity).setView(binding.getRoot()).create(); + public static RestoreDialog create() { + return new RestoreDialog(); } - public void show() { - initDialog(); - initEvent(); + public RestoreDialog callback(RestoreCallback callback) { + this.callback = callback; + return this; } - private void initDialog() { - dialog.getWindow().setDimAmount(0); - dialog.show(); + public void show(Activity activity) { + dialog = new ChooserDialog(activity); + dialog.withFilter(false, false, "tv", "backup"); + dialog.withStartFile(Path.tv().getAbsolutePath()); + dialog.withChosenListener(this::onChoosePath); + dialog.withOnBackPressedListener(d -> dialog.goBack()); + dialog.withOnLastBackPressedListener(d -> dialog.dismiss()); + dialog.build().show(); } - private void initEvent() { - binding.positive.setOnClickListener(this::onPositive); - binding.negative.setOnClickListener(this::onNegative); - } - - private void onPositive(View view) { - callback.onRestore(); - dialog.dismiss(); - } - private void onNegative(View view) { - dialog.dismiss(); + private void onChoosePath(String path, File pathFile) { + callback.onRestore(pathFile); + if (dialog != null) dialog.dismiss(); } } \ No newline at end of file diff --git a/app/src/leanback/res/layout/activity_setting.xml b/app/src/leanback/res/layout/activity_setting.xml index ecbdaa19b..408683f31 100644 --- a/app/src/leanback/res/layout/activity_setting.xml +++ b/app/src/leanback/res/layout/activity_setting.xml @@ -326,7 +326,7 @@ android:orientation="horizontal"> + tools:text="Auto" /> - - @@ -422,7 +413,7 @@ + tools:text="Google" /> @@ -457,6 +448,36 @@ android:layout_marginTop="16dp" android:orientation="horizontal"> + + + + + + + + { + File restore = Path.restore(); + if (!restore.exists()) return; File db = App.get().getDatabasePath(NAME).getAbsoluteFile(); File wal = App.get().getDatabasePath(NAME + "-wal").getAbsoluteFile(); File shm = App.get().getDatabasePath(NAME + "-shm").getAbsoluteFile(); - if (db.exists()) Path.copy(db, new File(Path.tv(), db.getName())); - if (wal.exists()) Path.copy(wal, new File(Path.tv(), wal.getName())); - if (shm.exists()) Path.copy(shm, new File(Path.tv(), shm.getName())); - Prefers.backup(new File(Path.tv(), NAME + "-pref")); + if (db.exists()) Path.copy(db, new File(restore, db.getName())); + if (wal.exists()) Path.copy(wal, new File(restore, wal.getName())); + if (shm.exists()) Path.copy(shm, new File(restore, shm.getName())); + Prefers.backup(new File(restore, NAME + "-pref")); + String time = Util.format(new SimpleDateFormat("yyyyMMddHHmm", Locale.getDefault()), (new File(restore, db.getName())).lastModified()); + FileUtil.zipFolder(restore, new File(Path.tv(), time + "." + BACKUP_SUFFIX)); App.post(callback::success); }); } - public static void restore(com.fongmi.android.tv.impl.Callback callback) { + public static void restore(File file, com.fongmi.android.tv.impl.Callback callback) { App.execute(() -> { - File db = new File(Path.tv(), NAME); - File wal = new File(Path.tv(), NAME + "-wal"); - File shm = new File(Path.tv(), NAME + "-shm"); - File pref = new File(Path.tv(), NAME + "-pref"); + File restore = Path.restore(); + if (!restore.exists()) return; + FileUtil.unzip(file, restore); + File db = new File(restore, NAME); + File wal = new File(restore, NAME + "-wal"); + File shm = new File(restore, NAME + "-shm"); + File pref = new File(restore, NAME + "-pref"); if (db.exists()) Path.copy(db, App.get().getDatabasePath(db.getName()).getAbsoluteFile()); if (wal.exists()) Path.copy(wal, App.get().getDatabasePath(wal.getName()).getAbsoluteFile()); if (shm.exists()) Path.copy(shm, App.get().getDatabasePath(shm.getName()).getAbsoluteFile()); diff --git a/app/src/main/java/com/fongmi/android/tv/impl/RestoreCallback.java b/app/src/main/java/com/fongmi/android/tv/impl/RestoreCallback.java index 57b975851..fc4fcfdfa 100644 --- a/app/src/main/java/com/fongmi/android/tv/impl/RestoreCallback.java +++ b/app/src/main/java/com/fongmi/android/tv/impl/RestoreCallback.java @@ -1,6 +1,8 @@ package com.fongmi.android.tv.impl; +import java.io.File; + public interface RestoreCallback { - void onRestore(); -} + void onRestore(File file); +} \ No newline at end of file diff --git a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java index dd81d8a04..30d65036f 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java @@ -12,11 +12,14 @@ import com.fongmi.android.tv.impl.Callback; import com.github.catvod.utils.Path; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.net.URLConnection; import java.text.DecimalFormat; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; public class FileUtil { @@ -32,6 +35,35 @@ public class FileUtil { App.get().startActivity(intent); } + public static void zipFolder(File folder, File zip) { + try { + ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zip)); + folderToZip("", folder, zipOut); + zipOut.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void folderToZip(String parentPath, File folder, ZipOutputStream zipOut) throws Exception { + for (File file : folder.listFiles()) { + if (file.isDirectory()) { + folderToZip(parentPath + file.getName() + "/", file, zipOut); + continue; + } + ZipEntry zipEntry = new ZipEntry(parentPath + file.getName()); + zipOut.putNextEntry(zipEntry); + + FileInputStream in = new FileInputStream(file); + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = in.read(buffer)) != -1) { + zipOut.write(buffer, 0, bytesRead); + } + in.close(); + } + } + public static void unzip(File target, File path) { try (ZipFile zip = new ZipFile(target)) { Enumeration entries = zip.entries(); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b1a16ced5..3201e84a1 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -95,7 +95,7 @@ Proxy 缓存 备份 - 自动 + 恢复 版本 关于 权限 @@ -176,6 +176,7 @@ 已复制 + 备份成功 接口已刷新 @@ -183,6 +184,11 @@ + + 自动 + 手动 + + 软解 硬解 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 5a1dd4df9..30d9292db 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -95,7 +95,7 @@ Proxy 暫存 備份 - 自動 + 恢復 版本 關於 權限 @@ -177,6 +177,7 @@ 已複製 + 備份成功 接口已刷新 @@ -184,6 +185,11 @@ + + 自動 + 手動 + + 軟解 硬解 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2e00bf8a0..8b4107b2f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -95,7 +95,7 @@ Proxy Cache Backup - Auto + Restore Version About Permission @@ -176,6 +176,7 @@ Copied + Backup successful Config rereshed @@ -183,6 +184,11 @@ times lines + + Auto + Manual + + Soft Hard diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/MainActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/MainActivity.java index 4c62e5b5d..3a69ed56f 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/MainActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/MainActivity.java @@ -1,11 +1,9 @@ package com.fongmi.android.tv.ui.activity; -import android.Manifest; import android.app.PendingIntent; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; -import android.text.TextUtils; import android.view.MenuItem; import android.view.View; @@ -41,9 +39,7 @@ import com.fongmi.android.tv.ui.fragment.VodFragment; import com.fongmi.android.tv.utils.FileChooser; import com.fongmi.android.tv.utils.Notify; import com.fongmi.android.tv.utils.UrlUtil; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.navigation.NavigationBarView; -import com.permissionx.guolindev.PermissionX; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; @@ -122,7 +118,6 @@ public class MainActivity extends BaseActivity implements NavigationBarView.OnIt @Override public void error(String msg) { - if (TextUtils.isEmpty(msg) && AppDatabase.getBackup().exists()) showRestoreDialog(); RefreshEvent.config(); StateEvent.empty(); Notify.show(msg); @@ -130,20 +125,6 @@ public class MainActivity extends BaseActivity implements NavigationBarView.OnIt }; } - private void showRestoreDialog() { - new MaterialAlertDialogBuilder(this).setTitle(R.string.dialog_restore).setMessage(R.string.dialog_restore_msg).setNegativeButton(R.string.dialog_negative, null).setPositiveButton(R.string.dialog_positive, (dialog, which) -> onRestore()).show(); - } - - private void onRestore() { - PermissionX.init(this).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> AppDatabase.restore(new Callback() { - @Override - public void success() { - if (allGranted) StateEvent.progress(); - if (allGranted) initConfig(); - } - })); - } - private void loadLive(String url) { LiveConfig.load(Config.find(url, 1), new Callback() { @Override diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java index 99dcb8ae9..77d6697f4 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java @@ -11,6 +11,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.viewbinding.ViewBinding; +import com.fongmi.android.tv.App; import com.fongmi.android.tv.BuildConfig; import com.fongmi.android.tv.R; import com.fongmi.android.tv.Setting; @@ -40,6 +41,7 @@ import com.fongmi.android.tv.ui.dialog.SiteDialog; import com.fongmi.android.tv.utils.FileChooser; import com.fongmi.android.tv.utils.FileUtil; import com.fongmi.android.tv.utils.Notify; +import com.fongmi.android.tv.utils.ResUtil; import com.fongmi.android.tv.utils.UrlUtil; import com.github.catvod.bean.Doh; import com.github.catvod.net.OkHttp; @@ -47,12 +49,14 @@ import com.github.catvod.utils.Path; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.permissionx.guolindev.PermissionX; +import java.io.File; import java.util.ArrayList; import java.util.List; public class SettingFragment extends BaseFragment implements ConfigCallback, SiteCallback, LiveCallback, ProxyCallback { private FragmentSettingBinding mBinding; + private String[] backup; private int type; public static SettingFragment newInstance() { @@ -83,9 +87,9 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit mBinding.vodUrl.setText(VodConfig.getDesc()); mBinding.liveUrl.setText(LiveConfig.getDesc()); mBinding.wallUrl.setText(WallConfig.getDesc()); - mBinding.backupText.setText(AppDatabase.getDate()); mBinding.dohText.setText(getDohList()[getDohIndex()]); mBinding.versionText.setText(BuildConfig.VERSION_NAME); + mBinding.backupText.setText((backup = ResUtil.getStringArray(R.array.select_backup))[Setting.getBackupMode()]); mBinding.aboutText.setText(BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_api + "-" + BuildConfig.FLAVOR_abi); mBinding.proxyText.setText(UrlUtil.scheme(Setting.getProxy())); setCacheText(); @@ -109,6 +113,7 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit mBinding.cache.setOnClickListener(this::onCache); mBinding.cache.setOnLongClickListener(this::onCacheLongClick); mBinding.backup.setOnClickListener(this::onBackup); + mBinding.restore.setOnClickListener(this::onRestore); mBinding.player.setOnClickListener(this::onPlayer); mBinding.version.setOnClickListener(this::onVersion); mBinding.vod.setOnLongClickListener(this::onVodEdit); @@ -116,7 +121,7 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit mBinding.live.setOnLongClickListener(this::onLiveEdit); mBinding.liveHome.setOnClickListener(this::onLiveHome); mBinding.wall.setOnLongClickListener(this::onWallEdit); - mBinding.backup.setOnLongClickListener(this::onBackupAuto); + mBinding.backup.setOnLongClickListener(this::onBackupMode); mBinding.vodHistory.setOnClickListener(this::onVodHistory); mBinding.version.setOnLongClickListener(this::onVersionDev); mBinding.liveHistory.setOnClickListener(this::onLiveHistory); @@ -341,18 +346,41 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit return true; } + private void onRestore(View view) { + FileChooser.from(this).show(); + } + + private void initConfig() { + WallConfig.get().init(); + LiveConfig.get().init().load(); + VodConfig.get().init().load(getCallback()); + } + + private void restore(File file) { + PermissionX.init(this).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> AppDatabase.restore(file, new Callback() { + @Override + public void success() { + if (allGranted) { + Notify.progress(getActivity()); + App.post(() -> initConfig(), 3000); + } + } + })); + } + private void onBackup(View view) { PermissionX.init(this).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> AppDatabase.backup(new Callback() { @Override public void success() { - mBinding.backupText.setText(AppDatabase.getDate()); + Notify.show(R.string.backed); } })); } - private boolean onBackupAuto(View view) { - Setting.putBackupAuto(!Setting.isBackupAuto()); - mBinding.backupText.setText(AppDatabase.getDate()); + private boolean onBackupMode(View view) { + int index = Setting.getBackupMode(); + Setting.putBackupMode(index = index == backup.length - 1 ? 0 : ++index); + mBinding.backupText.setText(backup[index]); return true; } @@ -370,6 +398,8 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != Activity.RESULT_OK || requestCode != FileChooser.REQUEST_PICK_FILE) return; - setConfig(Config.find("file:/" + FileChooser.getPathFromUri(getContext(), data.getData()).replace(Path.rootPath(), ""), type)); + String path = FileChooser.getPathFromUri(getContext(), data.getData()); + if (path.endsWith(AppDatabase.BACKUP_SUFFIX)) restore(new File(path)); + else setConfig(Config.find("file:/" + path.replace(Path.rootPath(), ""), type)); } } diff --git a/app/src/mobile/res/layout/fragment_setting.xml b/app/src/mobile/res/layout/fragment_setting.xml index d046b8dca..7b8048d93 100644 --- a/app/src/mobile/res/layout/fragment_setting.xml +++ b/app/src/mobile/res/layout/fragment_setting.xml @@ -355,6 +355,24 @@ + + + + + +