package ml.puredark.hviewer.ui.fragments;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.FragmentTransaction;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.support.annotation.NonNull;
import android.support.v4.provider.DocumentFile;
import android.support.v4.util.Pair;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.common.util.ByteConstants;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import net.rdrei.android.dirchooser.DirectoryChooserConfig;
import net.rdrei.android.dirchooser.DirectoryChooserFragment;
import java.util.ArrayList;
import java.util.List;
import ml.puredark.hviewer.HViewerApplication;
import ml.puredark.hviewer.R;
import ml.puredark.hviewer.beans.CollectionGroup;
import ml.puredark.hviewer.beans.LocalCollection;
import ml.puredark.hviewer.configs.Names;
import ml.puredark.hviewer.configs.UrlConfig;
import ml.puredark.hviewer.dataholders.DownloadTaskHolder;
import ml.puredark.hviewer.dataholders.FavouriteHolder;
import ml.puredark.hviewer.download.DownloadManager;
import ml.puredark.hviewer.helpers.DataBackup;
import ml.puredark.hviewer.helpers.DataRestore;
import ml.puredark.hviewer.helpers.DynamicIjkLibLoader;
import ml.puredark.hviewer.helpers.DynamicLibDownloader;
import ml.puredark.hviewer.helpers.FileHelper;
import ml.puredark.hviewer.helpers.Logger;
import ml.puredark.hviewer.helpers.UpdateManager;
import ml.puredark.hviewer.http.DownloadUtil;
import ml.puredark.hviewer.http.HViewerHttpClient;
import ml.puredark.hviewer.ui.activities.BaseActivity;
import ml.puredark.hviewer.ui.activities.LicenseActivity;
import ml.puredark.hviewer.ui.activities.PrivacyActivity;
import ml.puredark.hviewer.ui.preferences.LongClickPreference;
import ml.puredark.hviewer.utils.DensityUtil;
import ml.puredark.hviewer.utils.SharedPreferencesUtil;
import static android.app.Activity.RESULT_OK;
import static ml.puredark.hviewer.HViewerApplication.mContext;
/**
* Created by PureDark on 2016/9/25.
*/
public class SettingFragment extends PreferenceFragment
implements Preference.OnPreferenceChangeListener, DirectoryChooserFragment.OnFragmentInteractionListener {
public static final String KEY_PREF_PROXY_DETAIL = "pref_proxy_detail";
public static final String KEY_PREF_PROXY_ENABLED = "pref_proxy_enabled";
public static final String KEY_PREF_PROXY_REQUEST = "pref_proxy_request";
public static final String KEY_PREF_PROXY_PICTURE = "pref_proxy_picture";
public static final String KEY_PREF_PROXY_SERVER = "pref_proxy_server";
public static final String KEY_PRER_VIEW_REMLASTSITE = "pref_view_rememberLastSite";
public static final String KEY_PREF_VIEW_HIGH_RES = "pref_view_high_res";
public static final String KEY_PREF_VIEW_PRELOAD_PAGES = "pref_view_preload_pages";
public static final String KEY_PREF_VIEW_DIRECTION = "pref_view_direction";
public static final String KEY_PREF_VIEW_VOLUME_FLICK = "pref_view_volume_flick";
public static final String KEY_PREF_VIEW_ONE_PIC_GALLERY = "pref_view_one_pic_gallery";
public static final String KEY_PREF_VIEW_ONE_HAND = "pref_view_one_hand";
public static final String KEY_PREF_VIEW_VIDEO_PLAYER = "pref_view_video_player";
public static final String DIREACTION_LEFT_TO_RIGHT = mContext.getResources().getStringArray(R.array.settings_view_direction_values)[0];
public static final String DIREACTION_RIGHT_TO_LEFT = mContext.getResources().getStringArray(R.array.settings_view_direction_values)[1];
public static final String DIREACTION_TOP_TO_BOTTOM = mContext.getResources().getStringArray(R.array.settings_view_direction_values)[2];
public static final String VIDEO_IJKPLAYER = mContext.getResources().getStringArray(R.array.settings_view_video_player_values)[0];
public static final String VIDEO_H5PLAYER = mContext.getResources().getStringArray(R.array.settings_view_video_player_values)[1];
public static final String VIDEO_OTHERPLAYER = mContext.getResources().getStringArray(R.array.settings_view_video_player_values)[2];
public static final String KEY_PREF_DOWNLOAD_HIGH_RES = "pref_download_high_res";
public static final String KEY_PREF_DOWNLOAD_NOMEDIA = "pref_download_nomedia";
public static final String KEY_PREF_DOWNLOAD_PATH = "pref_download_path";
public static final String KEY_PREF_DOWNLOAD_IMPORT = "pref_download_import";
public static final String KEY_PREF_FAVOURITE_EXPORT = "pref_favourite_export";
public static final String KEY_PREF_FAVOURITE_IMPORT = "pref_favourite_import";
public static final String KEY_PREF_CACHE_SIZE = "pref_cache_size";
public static final String KEY_PREF_CACHE_CLEAN = "pref_cache_clean";
public static final String KEY_PREF_BKRS_BACKUP = "pref_backupandrestore_backup";
public static final String KEY_PREF_BKRS_RESTORE = "pref_backupandrestore_restore";
public static final String KEY_PREF_LOCK_METHODS_DETAIL = "pref_lock_methods_detail";
public static final String KEY_PREF_ABOUT_UPGRADE = "pref_about_upgrade";
public static final String KEY_PREF_ABOUT_LICENSE = "pref_about_license";
public static final String KEY_PREF_ABOUT_PRIVACY = "pref_about_privacy";
public static final String KEY_PREF_ABOUT_H_VIEWER = "pref_about_h_viewer";
public static final String KEY_PREF_MODE_R18_ENABLED = "pref_mode_r18_enabled";
public static final String KEY_LAST_SITE_ID = "last_site_id";
public static final String KEY_FIRST_TIME = "key_first_time";
public static final String KEY_CUSTOM_HEADER_IMAGE = "key_custom_header_image";
private static final int RESULT_CHOOSE_DIRECTORY = 1;
private BaseActivity activity;
private DirectoryChooserFragment mDialog;
private boolean checking = false;
//是否已打开路径选择器
private boolean opened = false;
public SettingFragment() {
}
@SuppressLint("ValidFragment")
public SettingFragment(BaseActivity activity) {
this.activity = activity;
}
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(SharedPreferencesUtil.FILE_NAME);
addPreferencesFromResource(R.xml.preferences);
String downloadPath = DownloadManager.getDownloadPath();
if (downloadPath != null) {
String displayPath = Uri.decode(downloadPath);
getPreferenceManager().findPreference(KEY_PREF_DOWNLOAD_PATH).setSummary(displayPath);
}
ListPreference listPreference = (ListPreference) getPreferenceManager().findPreference(KEY_PREF_VIEW_DIRECTION);
CharSequence[] entries = listPreference.getEntries();
int i = listPreference.findIndexOfValue(listPreference.getValue());
i = (i <= 0) ? 0 : i;
listPreference.setSummary(entries[i]);
listPreference.setOnPreferenceChangeListener(this);
listPreference = (ListPreference) getPreferenceManager().findPreference(KEY_PREF_VIEW_VIDEO_PLAYER);
entries = listPreference.getEntries();
i = listPreference.findIndexOfValue(listPreference.getValue());
i = (i <= 0) ? 0 : i;
listPreference.setSummary(entries[i]);
listPreference.setOnPreferenceChangeListener(this);
getPreferenceScreen().setOnPreferenceChangeListener(this);
final DirectoryChooserConfig config = DirectoryChooserConfig.builder()
.initialDirectory((downloadPath.startsWith("/")) ? downloadPath : DownloadManager.DEFAULT_PATH)
.newDirectoryName("download")
.allowNewDirectoryNameModification(true)
.build();
mDialog = DirectoryChooserFragment.newInstance(config);
mDialog.setTargetFragment(this, 0);
float size = (float) Fresco.getImagePipelineFactory().getMainFileCache().getSize() / ByteConstants.MB;
Preference cacheCleanPreference = getPreferenceManager().findPreference(KEY_PREF_CACHE_CLEAN);
cacheCleanPreference.setSummary(String.format("已使用 %.2f MB", size));
LongClickPreference prefDownloadPath = (LongClickPreference) getPreferenceManager().findPreference(KEY_PREF_DOWNLOAD_PATH);
prefDownloadPath.setOnLongClickListener(v -> {
new AlertDialog.Builder(activity)
.setTitle("选择路径方式")
.setItems(new String[]{"系统文档(新)", "路径选择框(旧)"}, (dialogInterface, pos) -> {
if (pos == 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
try {
startActivityForResult(intent, RESULT_CHOOSE_DIRECTORY);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
mDialog.show(getFragmentManager(), null);
}
new Handler().postDelayed(() -> {
if (!opened)
activity.showSnackBar("如无法开启系统文档,长按使用旧工具");
}, 1000);
} else if (pos == 1) {
mDialog.show(getFragmentManager(), null);
} else
activity.showSnackBar("当前系统版本不支持");
})
.setNegativeButton(getString(R.string.cancel), null)
.show();
return true;
});
}
@Override
public void onPause() {
super.onPause();
opened = true;
}
@Override
public void onResume() {
super.onResume();
opened = false;
}
@Override
public void onSelectDirectory(@NonNull String path) {
SharedPreferencesUtil.saveData(getActivity(), KEY_PREF_DOWNLOAD_PATH, Uri.encode(path));
getPreferenceManager().findPreference(KEY_PREF_DOWNLOAD_PATH).setSummary(Uri.decode(path));
mDialog.dismiss();
}
@Override
public void onCancelChooser() {
mDialog.dismiss();
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference.getKey().equals(KEY_PREF_PROXY_SERVER)) {
preference.setSummary((String) newValue);
} else if (preference.getKey().equals(KEY_PREF_VIEW_DIRECTION)) {
ListPreference directionPreference = (ListPreference) preference;
CharSequence[] entries = directionPreference.getEntries();
int i = directionPreference.findIndexOfValue((String) newValue);
i = (i <= 0) ? 0 : i;
directionPreference.setSummary(entries[i]);
} else if (preference.getKey().equals(KEY_PREF_VIEW_VIDEO_PLAYER)) {
ListPreference videoPlayerPreference = (ListPreference) preference;
CharSequence[] entries = videoPlayerPreference.getEntries();
int i = videoPlayerPreference.findIndexOfValue((String) newValue);
i = (i <= 0) ? 0 : i;
videoPlayerPreference.setSummary(entries[i]);
if (VIDEO_IJKPLAYER.equals(newValue) && !DynamicIjkLibLoader.isLibrariesDownloaded()) {
// 未下载播放器解码so包
new DynamicLibDownloader(activity).checkDownloadLib();
}
}
return true;
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (preference.getKey().equals(KEY_PREF_ABOUT_UPGRADE)) {
//检查新版本
if (!checking)
UpdateManager.checkUpdate(activity);
} else if (preference.getKey().equals(KEY_PREF_BKRS_BACKUP)) {
//备份
new AlertDialog.Builder(activity).setTitle("确认备份?")
.setMessage("将会覆盖之前的备份")
.setPositiveButton(getString(R.string.ok), (dialog, which) -> {
String backup = new DataBackup().DoBackup();
activity.showSnackBar(backup);
})
.setNegativeButton(getString(R.string.cancel), null).show();
} else if (preference.getKey().equals(KEY_PREF_BKRS_RESTORE)) {
//还原
new AlertDialog.Builder(activity).setTitle("确认恢复?")
.setMessage("如已存在同名站点,不会覆盖")
.setPositiveButton(getString(R.string.ok), (dialog, which) -> {
String restore = new DataRestore().DoRestore();
Intent intent = new Intent();
activity.setResult(RESULT_OK, intent);
Toast.makeText(activity, restore, Toast.LENGTH_LONG).show();
activity.finish();
})
.setNegativeButton(getString(R.string.cancel), null).show();
} else if (preference.getKey().equals(KEY_PREF_ABOUT_LICENSE)) {
//开源协议
Intent intent = new Intent(activity, LicenseActivity.class);
startActivity(intent);
} else if (preference.getKey().equals(KEY_PREF_ABOUT_PRIVACY)) {
//隐私权政策
Intent intent = new Intent(activity, PrivacyActivity.class);
startActivity(intent);
} else if (preference.getKey().equals(KEY_PREF_ABOUT_H_VIEWER)) {
//关于
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.setting_content, new AboutFragment(activity));
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.addToBackStack(null);
transaction.commit();
} else if (preference.getKey().equals(KEY_PREF_DOWNLOAD_PATH)) {
//下载路径
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
try {
startActivityForResult(intent, RESULT_CHOOSE_DIRECTORY);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
mDialog.show(getFragmentManager(), null);
}
new Handler().postDelayed(() -> {
if (!opened)
activity.showSnackBar("如无法开启系统文档,长按使用旧工具");
}, 1000);
} else {
mDialog.show(getFragmentManager(), null);
}
} else if (preference.getKey().equals(KEY_PREF_DOWNLOAD_IMPORT)) {
//导入已下载
new AlertDialog.Builder(activity).setTitle("确定要导入已下载图册?")
.setMessage("将从当前指定的下载目录进行搜索")
.setPositiveButton(getString(R.string.ok), (dialog, which) -> {
DownloadedImport();
})
.setNegativeButton(getString(R.string.cancel), null).show();
} else if (preference.getKey().equals(KEY_PREF_FAVOURITE_EXPORT)) {
//导出收藏夹
new AlertDialog.Builder(activity).setTitle("确定要导出收藏夹?")
.setMessage("将导出至当前指定的下载目录")
.setPositiveButton("确定", (dialog, which) -> {
DocumentFile file = FileHelper.createFileIfNotExist(Names.favouritesname, DownloadManager.getDownloadPath(), Names.backupdirname);
if (file != null) {
FavouriteHolder holder = new FavouriteHolder(activity);
String json = new Gson().toJson(holder.getFavourites());
FileHelper.writeString(json, file);
holder.onDestroy();
activity.showSnackBar("导出收藏夹成功");
} else
activity.showSnackBar("创建文件失败,请检查下载目录");
})
.setNegativeButton(getString(R.string.cancel), null).show();
} else if (preference.getKey().equals(KEY_PREF_FAVOURITE_IMPORT)) {
//导入收藏夹
new AlertDialog.Builder(activity).setTitle("确定要导入收藏夹?")
.setMessage("将从当前指定的下载目录搜索收藏夹备份")
.setPositiveButton(getString(R.string.ok), (dialog, which) -> {
String json = FileHelper.readString(Names.favouritesname, DownloadManager.getDownloadPath(), Names.backupdirname);
if (json == null) {
activity.showSnackBar("未在下载目录中找到收藏夹备份");
} else {
try {
List<Pair<CollectionGroup, List<LocalCollection>>> favGroups =
new Gson().fromJson(json, new TypeToken<ArrayList<Pair<CollectionGroup, ArrayList<LocalCollection>>>>() {
}.getType());
FavouriteHolder holder = new FavouriteHolder(activity);
for (Pair<CollectionGroup, List<LocalCollection>> pair : favGroups) {
Logger.d("DataStore", "" + pair.first);
CollectionGroup group = holder.getGroupByTitle(pair.first.title);
if (group == null) {
group = pair.first;
group.gid = holder.addFavGroup(group);
}
for (LocalCollection collection : pair.second) {
collection.gid = group.gid;
holder.addFavourite(collection);
}
}
holder.onDestroy();
activity.showSnackBar("导入收藏夹成功");
} catch (Exception e) {
e.printStackTrace();
activity.showSnackBar("导入收藏夹失败");
}
}
})
.setNegativeButton(getString(R.string.cancel), null).show();
} else if (preference.getKey().equals(KEY_PREF_CACHE_CLEAN)) {
//清空图片缓存
new AlertDialog.Builder(activity).setTitle("确定要清空图片缓存?")
.setMessage("近期加载过的图片将会需要重新下载")
.setPositiveButton(getString(R.string.ok), (dialog, which) -> {
ImagePipeline imagePipeline = Fresco.getImagePipeline();
imagePipeline.clearDiskCaches();
activity.showSnackBar("缓存清理成功");
preference.setSummary("已使用 0.00 MB");
})
.setNegativeButton(getString(R.string.cancel), null).show();
} else if (preference.getKey().equals(KEY_PREF_PROXY_DETAIL)) {
//PROXY代理
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.setting_content, new ProxyFragment(activity));
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.addToBackStack(null);
transaction.commit();
} else if (preference.getKey().equals(KEY_PREF_LOCK_METHODS_DETAIL)) {
//应用解锁方式
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.setting_content, new LockMethodFragment(activity));
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.addToBackStack(null);
transaction.commit();
}
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == RESULT_CHOOSE_DIRECTORY) {
Uri uriTree = data.getData();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
getActivity().getContentResolver().takePersistableUriPermission(
uriTree, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
} catch (SecurityException e) {
e.printStackTrace();
}
}
String path = uriTree.toString();
String displayPath = Uri.decode(path);
SharedPreferencesUtil.saveData(getActivity(), KEY_PREF_DOWNLOAD_PATH, path);
getPreferenceManager().findPreference(KEY_PREF_DOWNLOAD_PATH).setSummary(displayPath);
}
}
}
public void DownloadedImport() {
// 关闭边缘滑动返回
activity.setSwipeBackEnable(false);
// 阻止退出
activity.setAllowExit(false);
View view = LayoutInflater.from(activity).inflate(R.layout.dialog_loading, null);
TextView tvLoadingText = (TextView) view.findViewById(R.id.tv_loading_text);
tvLoadingText.setText("正在导入已下载图册");
final Dialog dialog = new AlertDialog.Builder(activity)
.setView(view)
.create();
dialog.setCanceledOnTouchOutside(false);
//设置对话框位置
WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
lp.width = DensityUtil.getScreenWidth(activity) - DensityUtil.dp2px(activity, 64);
dialog.getWindow().setAttributes(lp);
dialog.show();
new Thread(() -> {
DownloadTaskHolder holder = new DownloadTaskHolder(activity);
final int count = holder.scanPathForDownloadTask(DownloadManager.getDownloadPath());
holder.onDestroy();
activity.runOnUiThread(() -> {
if (count > 0)
Toast.makeText(mContext, "成功导入" + count + "个已下载图册", Toast.LENGTH_SHORT).show();
else if (count == 0)
Toast.makeText(mContext, "未发现不在下载管理中的已下载图册", Toast.LENGTH_SHORT).show();
else
Toast.makeText(mContext, "导入失败", Toast.LENGTH_SHORT).show();
});
activity.setSwipeBackEnable(true);
activity.setAllowExit(true);
dialog.dismiss();
}).start();
}
}