From 60a91866026cf607bb831529fc2e2b3bf3d6fce5 Mon Sep 17 00:00:00 2001 From: FongMi Date: Sat, 4 Nov 2023 00:25:34 +0800 Subject: [PATCH] Support backup db --- app/build.gradle | 4 +- .../android/tv/receiver/BootReceiver.java | 1 - .../android/tv/ui/activity/CastActivity.java | 4 +- .../android/tv/ui/activity/HomeActivity.java | 18 ++++++++- .../tv/ui/activity/SettingActivity.java | 12 ++++++ .../android/tv/ui/activity/VideoActivity.java | 3 +- .../leanback/res/layout/activity_setting.xml | 36 +++++++++++++++-- .../com/fongmi/android/tv/db/AppDatabase.java | 40 ++++++++++++++++++- .../com/fongmi/android/tv/utils/Util.java | 8 ++++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values-zh-rTW/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + .../android/tv/ui/activity/MainActivity.java | 18 ++++++++- .../android/tv/ui/activity/VideoActivity.java | 3 +- .../tv/ui/fragment/SettingFragment.java | 12 ++++++ .../mobile/res/layout/fragment_setting.xml | 27 +++++++++++++ .../java/com/github/catvod/utils/Path.java | 4 ++ 17 files changed, 175 insertions(+), 18 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a86896f30..fa958b730 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,12 +21,12 @@ android { leanback { dimension "mode" versionCode 207 - versionName "20231103#2" + versionName "20231104" } mobile { dimension "mode" versionCode 207 - versionName "20231103#2" + versionName "20231104" } java { dimension "api" diff --git a/app/src/leanback/java/com/fongmi/android/tv/receiver/BootReceiver.java b/app/src/leanback/java/com/fongmi/android/tv/receiver/BootReceiver.java index 236378bac..75e9d8df0 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/receiver/BootReceiver.java +++ b/app/src/leanback/java/com/fongmi/android/tv/receiver/BootReceiver.java @@ -13,6 +13,5 @@ public class BootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { DLNARendererService.Companion.start(App.get(), R.drawable.ic_logo); - context.startActivity(context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } } diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CastActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CastActivity.java index a416df584..51bb4049b 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CastActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CastActivity.java @@ -401,8 +401,8 @@ public class CastActivity extends BaseActivity implements CustomKeyDownCast.List @Override public void onTimeChanged() { - position = mPlayers.getPosition(); - duration = mPlayers.getDuration(); + App.post(() -> position = mPlayers.getPosition()); + App.post(() -> duration = mPlayers.getDuration()); } @Override 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 5d7a4f71b..ed50a7992 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 @@ -1,7 +1,9 @@ package com.fongmi.android.tv.ui.activity; +import android.Manifest; import android.content.Intent; import android.net.Uri; +import android.text.TextUtils; import android.view.KeyEvent; import android.view.View; @@ -31,6 +33,7 @@ import com.fongmi.android.tv.bean.Site; import com.fongmi.android.tv.bean.Style; import com.fongmi.android.tv.bean.Vod; import com.fongmi.android.tv.databinding.ActivityHomeBinding; +import com.fongmi.android.tv.db.AppDatabase; import com.fongmi.android.tv.event.CastEvent; import com.fongmi.android.tv.event.RefreshEvent; import com.fongmi.android.tv.event.ServerEvent; @@ -55,6 +58,7 @@ import com.fongmi.android.tv.utils.Notify; import com.fongmi.android.tv.utils.ResUtil; import com.fongmi.android.tv.utils.UrlUtil; import com.google.common.collect.Lists; +import com.permissionx.guolindev.PermissionX; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; @@ -169,7 +173,8 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen @Override public void error(String msg) { - mBinding.progressLayout.showContent(); + if (TextUtils.isEmpty(msg) && AppDatabase.getDate().length() > 0) onRestore(); + else mBinding.progressLayout.showContent(); mResult = Result.empty(); Notify.show(msg); setFocus(); @@ -177,6 +182,15 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen }; } + private void onRestore() { + PermissionX.init(this).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> AppDatabase.restore(new Callback() { + @Override + public void success() { + initConfig(); + } + })); + } + private void loadLive(String url) { LiveConfig.load(Config.find(url, 1), new Callback() { @Override @@ -422,7 +436,7 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen } else if (!confirm) { setConfirm(); } else { - finish(); + super.onBackPressed(); } } 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 8b1123f9e..9b58b5448 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 @@ -18,6 +18,7 @@ import com.fongmi.android.tv.bean.Config; import com.fongmi.android.tv.bean.Live; import com.fongmi.android.tv.bean.Site; import com.fongmi.android.tv.databinding.ActivitySettingBinding; +import com.fongmi.android.tv.db.AppDatabase; import com.fongmi.android.tv.event.RefreshEvent; import com.fongmi.android.tv.impl.Callback; import com.fongmi.android.tv.impl.ConfigCallback; @@ -79,6 +80,7 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit mBinding.vodUrl.setText(ApiConfig.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())); @@ -107,6 +109,7 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit mBinding.wall.setOnClickListener(this::onWall); mBinding.proxy.setOnClickListener(this::onProxy); mBinding.cache.setOnClickListener(this::onCache); + mBinding.backup.setOnClickListener(this::onBackup); mBinding.version.setOnClickListener(this::onVersion); mBinding.vod.setOnLongClickListener(this::onVodEdit); mBinding.vodHome.setOnClickListener(this::onVodHome); @@ -350,4 +353,13 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit } }); } + + 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()); + } + })); + } } diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java index be54fe84b..63dbd0e7b 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java @@ -154,8 +154,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List public static void file(FragmentActivity activity, String path) { if (TextUtils.isEmpty(path)) return; String name = new File(path).getName(); - if (PermissionX.isGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) start(activity, "push_agent", "file://" + path, name, true); - else PermissionX.init(activity).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> start(activity, "push_agent", "file://" + path, name, true)); + PermissionX.init(activity).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> start(activity, "push_agent", "file://" + path, name, true)); } public static void cast(Activity activity, History history) { diff --git a/app/src/leanback/res/layout/activity_setting.xml b/app/src/leanback/res/layout/activity_setting.xml index 4d941f724..2e59537d5 100644 --- a/app/src/leanback/res/layout/activity_setting.xml +++ b/app/src/leanback/res/layout/activity_setting.xml @@ -512,7 +512,7 @@ + tools:text="20231103" /> + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java b/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java index a66ad3c2e..3154e1961 100644 --- a/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java +++ b/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java @@ -23,11 +23,18 @@ import com.fongmi.android.tv.db.dao.HistoryDao; import com.fongmi.android.tv.db.dao.KeepDao; import com.fongmi.android.tv.db.dao.SiteDao; import com.fongmi.android.tv.db.dao.TrackDao; +import com.fongmi.android.tv.utils.Util; +import com.github.catvod.utils.Path; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Locale; @Database(entities = {Keep.class, Site.class, Track.class, Config.class, Device.class, History.class}, version = AppDatabase.VERSION) public abstract class AppDatabase extends RoomDatabase { public static final int VERSION = 25; + public static final String NAME = "tv"; public static final String SYMBOL = "@@@"; private static volatile AppDatabase instance; @@ -37,8 +44,39 @@ public abstract class AppDatabase extends RoomDatabase { return instance; } + public static String getDate() { + File file = new File(Path.tv(), NAME); + return file.exists() ? Util.format(new SimpleDateFormat("yyyyMMdd", Locale.getDefault()), file.lastModified()) : ""; + } + + public static void backup(com.fongmi.android.tv.impl.Callback callback) { + App.execute(() -> { + File db = App.get().getDatabasePath(NAME).getAbsoluteFile(); + File wal = App.get().getDatabasePath(NAME + "-wal").getAbsoluteFile(); + File shm = App.get().getDatabasePath(NAME + "-shm").getAbsoluteFile(); + boolean exists = db.exists() && wal.exists() && shm.exists(); + if (exists) Path.copy(db, new File(Path.tv(), db.getName())); + if (exists) Path.copy(wal, new File(Path.tv(), wal.getName())); + if (exists) Path.copy(shm, new File(Path.tv(), shm.getName())); + if (exists) App.post(callback::success); + }); + } + + public static void restore(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"); + boolean exists = db.exists() && wal.exists() && shm.exists(); + if (exists) Path.copy(db, App.get().getDatabasePath(db.getName()).getAbsoluteFile()); + if (exists) Path.copy(wal, App.get().getDatabasePath(wal.getName()).getAbsoluteFile()); + if (exists) Path.copy(shm, App.get().getDatabasePath(shm.getName()).getAbsoluteFile()); + if (exists) App.post(callback::success); + }); + } + private static AppDatabase create(Context context) { - return Room.databaseBuilder(context, AppDatabase.class, "tv") + return Room.databaseBuilder(context, AppDatabase.class, NAME) .addMigrations(MIGRATION_11_12) .addMigrations(MIGRATION_12_13) .addMigrations(MIGRATION_13_14) diff --git a/app/src/main/java/com/fongmi/android/tv/utils/Util.java b/app/src/main/java/com/fongmi/android/tv/utils/Util.java index eff4d8220..b7a543fc4 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/Util.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/Util.java @@ -100,6 +100,14 @@ public class Util { } } + public static String format(SimpleDateFormat format, long time) { + try { + return format.format(time); + } catch (Exception e) { + return ""; + } + } + public static String format(StringBuilder builder, Formatter formatter, long timeMs) { try { return androidx.media3.common.util.Util.getStringForTime(builder, formatter, timeMs); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d61857907..834acb720 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -81,6 +81,7 @@ DoH Proxy 缓存 + 备份 版本 权限 关闭 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 70abd642b..605693d18 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -81,6 +81,7 @@ DoH Proxy 暫存 + 備份 版本 權限 關閉 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e20a6039f..0dbbee37b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -81,6 +81,7 @@ DoH Proxy Cache + Backup Version Permission Off 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 bd86fa761..6eb2892dd 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,9 +1,11 @@ package com.fongmi.android.tv.ui.activity; +import android.Manifest; import android.content.Intent; import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; +import android.text.TextUtils; import android.view.MenuItem; import androidx.annotation.NonNull; @@ -18,6 +20,7 @@ import com.fongmi.android.tv.api.LiveConfig; import com.fongmi.android.tv.api.WallConfig; import com.fongmi.android.tv.bean.Config; import com.fongmi.android.tv.databinding.ActivityMainBinding; +import com.fongmi.android.tv.db.AppDatabase; import com.fongmi.android.tv.event.RefreshEvent; import com.fongmi.android.tv.event.ServerEvent; import com.fongmi.android.tv.impl.Callback; @@ -32,6 +35,7 @@ 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.navigation.NavigationBarView; +import com.permissionx.guolindev.PermissionX; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; @@ -108,13 +112,23 @@ public class MainActivity extends BaseActivity implements NavigationBarView.OnIt @Override public void error(String msg) { + if (TextUtils.isEmpty(msg) && AppDatabase.getDate().length() > 0) onRestore(); + else RefreshEvent.empty(); RefreshEvent.config(); - RefreshEvent.empty(); Notify.show(msg); } }; } + private void onRestore() { + PermissionX.init(this).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> AppDatabase.restore(new Callback() { + @Override + public void success() { + initConfig(); + } + })); + } + private void loadLive(String url) { LiveConfig.load(Config.find(url, 1), new Callback() { @Override @@ -182,7 +196,7 @@ public class MainActivity extends BaseActivity implements NavigationBarView.OnIt mBinding.navigation.setSelectedItemId(R.id.vod); } else if (mManager.canBack(0)) { if (!confirm) setConfirm(); - else finish(); + else super.onBackPressed(); } } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java index 955615239..886548d91 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java @@ -164,8 +164,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo public static void file(FragmentActivity activity, String path) { if (TextUtils.isEmpty(path)) return; String name = new File(path).getName(); - if (PermissionX.isGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) start(activity, "push_agent", "file://" + path, name); - else PermissionX.init(activity).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> start(activity, "push_agent", "file://" + path, name)); + PermissionX.init(activity).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> start(activity, "push_agent", "file://" + path, name)); } public static void cast(Activity activity, History history) { 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 8cb9c013a..c52a14bed 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 @@ -22,6 +22,7 @@ import com.fongmi.android.tv.bean.Config; import com.fongmi.android.tv.bean.Live; import com.fongmi.android.tv.bean.Site; import com.fongmi.android.tv.databinding.FragmentSettingBinding; +import com.fongmi.android.tv.db.AppDatabase; import com.fongmi.android.tv.event.RefreshEvent; import com.fongmi.android.tv.impl.Callback; import com.fongmi.android.tv.impl.ConfigCallback; @@ -88,6 +89,7 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit mBinding.vodUrl.setText(ApiConfig.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())); @@ -115,6 +117,7 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit mBinding.wall.setOnClickListener(this::onWall); mBinding.proxy.setOnClickListener(this::onProxy); mBinding.cache.setOnClickListener(this::onCache); + mBinding.backup.setOnClickListener(this::onBackup); mBinding.version.setOnClickListener(this::onVersion); mBinding.vod.setOnLongClickListener(this::onVodEdit); mBinding.vodHome.setOnClickListener(this::onVodHome); @@ -358,6 +361,15 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit }); } + 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()); + } + })); + } + @Override public void onHiddenChanged(boolean hidden) { if (hidden || player == null || decode == null) return; diff --git a/app/src/mobile/res/layout/fragment_setting.xml b/app/src/mobile/res/layout/fragment_setting.xml index b4515cb8f..efef97772 100644 --- a/app/src/mobile/res/layout/fragment_setting.xml +++ b/app/src/mobile/res/layout/fragment_setting.xml @@ -426,6 +426,33 @@ + + + + + + + +