Rewrite backup and restore - part 2

pull/586/head
FongMi 1 year ago
parent 0b8ba42c33
commit 3b1c956f39
  1. 19
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java
  2. 50
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingActivity.java
  3. 77
      app/src/leanback/java/com/fongmi/android/tv/ui/adapter/RestoreAdapter.java
  4. 52
      app/src/leanback/java/com/fongmi/android/tv/ui/dialog/RestoreDialog.java
  5. 83
      app/src/leanback/res/layout/activity_setting.xml
  6. 35
      app/src/leanback/res/layout/adapter_restore.xml
  7. 50
      app/src/leanback/res/layout/dialog_restore.xml
  8. 3
      app/src/leanback/res/values-zh-rCN/strings.xml
  9. 3
      app/src/leanback/res/values-zh-rTW/strings.xml
  10. 3
      app/src/leanback/res/values/strings.xml
  11. 8
      app/src/main/java/com/fongmi/android/tv/Setting.java
  12. 6
      app/src/main/java/com/fongmi/android/tv/impl/RestoreCallback.java

@ -1,9 +1,7 @@
package com.fongmi.android.tv.ui.activity;
import android.Manifest;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
@ -43,7 +41,6 @@ import com.fongmi.android.tv.event.CastEvent;
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.RestoreCallback;
import com.fongmi.android.tv.model.SiteViewModel;
import com.fongmi.android.tv.player.Source;
import com.fongmi.android.tv.server.Server;
@ -51,7 +48,6 @@ import com.fongmi.android.tv.ui.base.BaseActivity;
import com.fongmi.android.tv.ui.custom.CustomRowPresenter;
import com.fongmi.android.tv.ui.custom.CustomSelector;
import com.fongmi.android.tv.ui.custom.CustomTitleView;
import com.fongmi.android.tv.ui.dialog.RestoreDialog;
import com.fongmi.android.tv.ui.dialog.SiteDialog;
import com.fongmi.android.tv.ui.presenter.FuncPresenter;
import com.fongmi.android.tv.ui.presenter.HeaderPresenter;
@ -65,14 +61,13 @@ 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;
import java.util.List;
public class HomeActivity extends BaseActivity implements CustomTitleView.Listener, RestoreCallback, VodPresenter.OnClickListener, FuncPresenter.OnClickListener, HistoryPresenter.OnClickListener {
public class HomeActivity extends BaseActivity implements CustomTitleView.Listener, VodPresenter.OnClickListener, FuncPresenter.OnClickListener, HistoryPresenter.OnClickListener {
private ActivityHomeBinding mBinding;
private ArrayObjectAdapter mHistoryAdapter;
@ -190,7 +185,6 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen
@Override
public void error(String msg) {
if (TextUtils.isEmpty(msg) && AppDatabase.getBackup().exists() && !VodConfig.hasUrl() && !LiveConfig.hasUrl()) RestoreDialog.create(getActivity()).show();
mBinding.progressLayout.showContent();
mResult = Result.empty();
Notify.show(msg);
@ -439,17 +433,6 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen
getVideo();
}
@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) mBinding.progressLayout.showProgress();
if (allGranted) initConfig();
}
}));
}
@Override
public void setSite(Site item) {
VodConfig.get().setHome(item);

@ -33,6 +33,7 @@ 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;
@ -49,7 +50,6 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
private ActivitySettingBinding mBinding;
private String[] quality;
private String[] backup;
private String[] size;
private int type;
@ -91,7 +91,6 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
mBinding.proxyText.setText(getProxy(Setting.getProxy()));
mBinding.incognitoText.setText(getSwitch(Setting.isIncognito()));
mBinding.sizeText.setText((size = ResUtil.getStringArray(R.array.select_size))[Setting.getSize()]);
mBinding.backupText.setText((backup = ResUtil.getStringArray(R.array.select_backup))[Setting.getBackupMode()]);
mBinding.qualityText.setText((quality = ResUtil.getStringArray(R.array.select_quality))[Setting.getQuality()]);
setCacheText();
}
@ -114,13 +113,13 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
mBinding.cache.setOnClickListener(this::onCache);
mBinding.backup.setOnClickListener(this::onBackup);
mBinding.player.setOnClickListener(this::onPlayer);
mBinding.restore.setOnClickListener(this::onRestore);
mBinding.version.setOnClickListener(this::onVersion);
mBinding.vod.setOnLongClickListener(this::onVodEdit);
mBinding.vodHome.setOnClickListener(this::onVodHome);
mBinding.live.setOnLongClickListener(this::onLiveEdit);
mBinding.liveHome.setOnClickListener(this::onLiveHome);
mBinding.wall.setOnLongClickListener(this::onWallEdit);
mBinding.backup.setOnLongClickListener(this::onBackupMode);
mBinding.vodHistory.setOnClickListener(this::onVodHistory);
mBinding.version.setOnLongClickListener(this::onVersionDev);
mBinding.liveHistory.setOnClickListener(this::onLiveHistory);
@ -145,23 +144,23 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
switch (config.getType()) {
case 0:
Notify.progress(this);
VodConfig.load(config, getCallback());
VodConfig.load(config, getCallback(0));
mBinding.vodUrl.setText(config.getDesc());
break;
case 1:
Notify.progress(this);
LiveConfig.load(config, getCallback());
LiveConfig.load(config, getCallback(1));
mBinding.liveUrl.setText(config.getDesc());
break;
case 2:
Notify.progress(this);
WallConfig.load(config, getCallback());
WallConfig.load(config, getCallback(2));
mBinding.wallUrl.setText(config.getDesc());
break;
}
}
private Callback getCallback() {
private Callback getCallback(int type) {
return new Callback() {
@Override
public void success(String result) {
@ -170,18 +169,18 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
@Override
public void success() {
setConfig();
setConfig(type);
}
@Override
public void error(String msg) {
Notify.show(msg);
setConfig();
setConfig(type);
}
};
}
private void setConfig() {
private void setConfig(int type) {
switch (type) {
case 0:
setCacheText();
@ -322,7 +321,7 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
Notify.progress(getActivity());
Setting.putDoh(doh.toString());
mBinding.dohText.setText(doh.getName());
VodConfig.load(Config.vod(), getCallback());
VodConfig.load(Config.vod(), getCallback(0));
}
private void onProxy(View view) {
@ -335,7 +334,7 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
Setting.putProxy(proxy);
OkHttp.get().setProxy(proxy);
Notify.progress(getActivity());
VodConfig.load(Config.vod(), getCallback());
VodConfig.load(Config.vod(), getCallback(0));
mBinding.proxyText.setText(getProxy(proxy));
}
@ -352,15 +351,30 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
PermissionX.init(this).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> AppDatabase.backup(new Callback() {
@Override
public void success() {
Notify.show(R.string.backed);
Notify.show(R.string.backup_success);
}
}));
}
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;
private void onRestore(View view) {
PermissionX.init(this).permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE).request((allGranted, grantedList, deniedList) -> RestoreDialog.create(this).show(new Callback() {
@Override
public void success() {
Notify.show(R.string.restore_success);
Notify.progress(getActivity());
initConfig();
}
@Override
public void error() {
Notify.show(R.string.restore_fail);
}
}));
}
private void initConfig() {
WallConfig.get().init();
LiveConfig.get().init().load();
VodConfig.get().init().load(getCallback(0));
}
}

@ -0,0 +1,77 @@
package com.fongmi.android.tv.ui.adapter;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.fongmi.android.tv.databinding.AdapterRestoreBinding;
import com.github.catvod.utils.Path;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class RestoreAdapter extends RecyclerView.Adapter<RestoreAdapter.ViewHolder> {
private final OnClickListener mListener;
private final List<File> mItems;
public RestoreAdapter(OnClickListener listener) {
this.mItems = new ArrayList<>();
this.mListener = listener;
this.addAll();
}
public interface OnClickListener {
void onItemClick(File item);
void onDeleteClick(File item);
}
public void addAll() {
File[] files = Path.tv().listFiles();
if (files == null || files.length == 0) return;
for (File file : files) if (file.getName().startsWith("tv") && file.getName().endsWith(".bk.gz")) mItems.add(file);
notifyDataSetChanged();
}
public void remove(File item) {
int position = mItems.indexOf(item);
if (position == -1) return;
Path.clear(item);
mItems.remove(position);
notifyItemRemoved(position);
}
@Override
public int getItemCount() {
return mItems.size();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(AdapterRestoreBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
File item = mItems.get(position);
holder.binding.text.setText(item.getName());
holder.binding.text.setOnClickListener(v -> mListener.onItemClick(item));
holder.binding.delete.setOnClickListener(v -> mListener.onDeleteClick(item));
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final AdapterRestoreBinding binding;
public ViewHolder(@NonNull AdapterRestoreBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}

@ -2,51 +2,67 @@ package com.fongmi.android.tv.ui.dialog;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import androidx.appcompat.app.AlertDialog;
import com.fongmi.android.tv.databinding.DialogRestoreBinding;
import com.fongmi.android.tv.impl.RestoreCallback;
import com.fongmi.android.tv.db.AppDatabase;
import com.fongmi.android.tv.impl.Callback;
import com.fongmi.android.tv.ui.adapter.RestoreAdapter;
import com.fongmi.android.tv.ui.custom.SpaceItemDecoration;
import com.fongmi.android.tv.utils.ResUtil;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
public class RestoreDialog {
import java.io.File;
public class RestoreDialog implements RestoreAdapter.OnClickListener {
private final DialogRestoreBinding binding;
private final RestoreCallback callback;
private final RestoreAdapter adapter;
private final AlertDialog dialog;
private Callback callback;
public static RestoreDialog create(Activity activity) {
return new RestoreDialog(activity);
}
public RestoreDialog(Activity activity) {
this.callback = (RestoreCallback) activity;
this.binding = DialogRestoreBinding.inflate(LayoutInflater.from(activity));
this.dialog = new MaterialAlertDialogBuilder(activity).setView(binding.getRoot()).create();
this.adapter = new RestoreAdapter(this);
}
public void show() {
initDialog();
initEvent();
public void show(Callback callback) {
this.callback = callback;
setRecyclerView();
setDialog();
}
private void initDialog() {
dialog.getWindow().setDimAmount(0);
dialog.show();
private void setRecyclerView() {
binding.recycler.setAdapter(adapter);
binding.recycler.setHasFixedSize(false);
binding.recycler.addItemDecoration(new SpaceItemDecoration(1, 16));
}
private void initEvent() {
binding.positive.setOnClickListener(this::onPositive);
binding.negative.setOnClickListener(this::onNegative);
private void setDialog() {
if (adapter.getItemCount() == 0) return;
WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
params.width = (int) (ResUtil.getScreenWidth() * 0.4f);
dialog.getWindow().setAttributes(params);
dialog.getWindow().setDimAmount(0);
dialog.show();
}
private void onPositive(View view) {
callback.onRestore();
@Override
public void onItemClick(File item) {
AppDatabase.restore(item, callback);
dialog.dismiss();
}
private void onNegative(View view) {
dialog.dismiss();
@Override
public void onDeleteClick(File item) {
if (adapter.getItemCount() == 1) dialog.dismiss();
adapter.remove(item);
}
}

@ -397,6 +397,52 @@
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/backup"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:background="@drawable/selector_item"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/setting_backup"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/restore"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/selector_item"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/setting_restore"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -434,7 +480,7 @@
</LinearLayout>
<LinearLayout
android:id="@+id/backup"
android:id="@+id/version"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
@ -447,49 +493,20 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:text="@string/setting_backup"
android:text="@string/setting_version"
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:id="@+id/backupText"
android:id="@+id/versionText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:textColor="@color/white"
android:textSize="18sp"
tools:text="20231103" />
tools:text="1.2.1" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/selector_item"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:text="@string/setting_version"
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:id="@+id/versionText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:textColor="@color/white"
android:textSize="18sp"
tools:text="1.2.1" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:background="@drawable/selector_text"
android:ellipsize="middle"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="18sp"
tools:text="tv-2024-12-26.bk.gz" />
<ImageView
android:id="@+id/delete"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:padding="8dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_setting_delete" />
</LinearLayout>

@ -1,47 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.fongmi.android.tv.ui.custom.CustomRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="@string/dialog_restore_msg"
android:textColor="@color/grey_900"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/positive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:text="@string/dialog_positive"
android:textColor="@color/white" />
<TextView
android:id="@+id/negative"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:text="@string/dialog_negative"
android:textColor="@color/white" />
</LinearLayout>
</LinearLayout>
android:padding="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:maxHeight="352dp" />

@ -17,7 +17,4 @@
<string name="push_clip">推送剪贴板内容</string>
<string name="push_info">使用手机扫描二维码,或于浏览器访问地址\n<xliff:g name="name">%s</xliff:g></string>
<!-- Dialog -->
<string name="dialog_restore_msg">是否要还原备份数据?</string>
</resources>

@ -17,7 +17,4 @@
<string name="push_clip">推送剪貼簿內容</string>
<string name="push_info">使用手機掃描 QR Code,或於瀏覽器輸入網址\n<xliff:g name="name">%s</xliff:g></string>
<!-- Dialog -->
<string name="dialog_restore_msg">是否要還原備份資料?</string>
</resources>

@ -17,7 +17,4 @@
<string name="push_clip">Push clipboard content</string>
<string name="push_info">Scan QR Code or enter the URL in browser\n<xliff:g name="name">%s</xliff:g></string>
<!-- Dialog -->
<string name="dialog_restore_msg">Restore backup data?</string>
</resources>

@ -161,14 +161,6 @@ public class Setting {
Prefers.put("sync_mode", mode);
}
public static int getBackupMode() {
return Prefers.getInt("backup_mode");
}
public static void putBackupMode(int auto) {
Prefers.put("backup_mode", auto);
}
public static boolean isIncognito() {
return Prefers.getBoolean("incognito");
}

@ -1,6 +0,0 @@
package com.fongmi.android.tv.impl;
public interface RestoreCallback {
void onRestore();
}
Loading…
Cancel
Save