@ -1,6 +1,7 @@ |
|||||||
<?xml version="1.0" encoding="UTF-8"?> |
<?xml version="1.0" encoding="UTF-8"?> |
||||||
<project version="4"> |
<project version="4"> |
||||||
<component name="SqlDialectMappings"> |
<component name="SqlDialectMappings"> |
||||||
|
<file url="file://$PROJECT_DIR$/app/src/main/java/xyz/fycz/myreader/model/backup/UserService.java" dialect="GenericSQL" /> |
||||||
<file url="PROJECT" dialect="MySQL" /> |
<file url="PROJECT" dialect="MySQL" /> |
||||||
</component> |
</component> |
||||||
</project> |
</project> |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 144 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 112 KiB |
After Width: | Height: | Size: 272 B |
After Width: | Height: | Size: 269 B |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 148 B |
After Width: | Height: | Size: 168 B |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 399 B |
After Width: | Height: | Size: 453 B |
After Width: | Height: | Size: 647 B |
After Width: | Height: | Size: 295 B |
After Width: | Height: | Size: 741 B |
After Width: | Height: | Size: 707 B |
After Width: | Height: | Size: 581 B |
After Width: | Height: | Size: 718 B |
After Width: | Height: | Size: 533 B |
After Width: | Height: | Size: 633 B |
After Width: | Height: | Size: 682 B |
After Width: | Height: | Size: 702 B |
After Width: | Height: | Size: 693 B |
After Width: | Height: | Size: 602 B |
After Width: | Height: | Size: 501 B |
After Width: | Height: | Size: 634 B |
After Width: | Height: | Size: 588 B |
After Width: | Height: | Size: 514 B |
After Width: | Height: | Size: 561 B |
After Width: | Height: | Size: 612 B |
After Width: | Height: | Size: 505 B |
After Width: | Height: | Size: 475 B |
After Width: | Height: | Size: 579 B |
After Width: | Height: | Size: 678 KiB |
@ -0,0 +1,813 @@ |
|||||||
|
//Copyright (c) 2017. 章钦豪. All rights reserved.
|
||||||
|
package xyz.fycz.myreader.entity; |
||||||
|
|
||||||
|
import android.content.ContentResolver; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.SharedPreferences; |
||||||
|
import android.content.res.Resources; |
||||||
|
import android.graphics.Bitmap; |
||||||
|
import android.graphics.Color; |
||||||
|
import android.graphics.drawable.BitmapDrawable; |
||||||
|
import android.graphics.drawable.ColorDrawable; |
||||||
|
import android.graphics.drawable.Drawable; |
||||||
|
import android.provider.Settings; |
||||||
|
import android.util.DisplayMetrics; |
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import xyz.fycz.myreader.application.MyApplication; |
||||||
|
import xyz.fycz.myreader.util.SharedPreUtils; |
||||||
|
import xyz.fycz.myreader.util.utils.BitmapUtil; |
||||||
|
import xyz.fycz.myreader.util.utils.MeUtils; |
||||||
|
|
||||||
|
import static xyz.fycz.myreader.widget.page2.PageLoader.DEFAULT_MARGIN_WIDTH; |
||||||
|
|
||||||
|
|
||||||
|
public class ReadBookControl { |
||||||
|
private static final int DEFAULT_BG = 1; |
||||||
|
private int textDrawableIndex = DEFAULT_BG; |
||||||
|
private List<Map<String, Integer>> textDrawable; |
||||||
|
private Bitmap bgBitmap; |
||||||
|
private int screenDirection; |
||||||
|
private int speechRate; |
||||||
|
private boolean speechRateFollowSys; |
||||||
|
private int textSize; |
||||||
|
private int textColor; |
||||||
|
private boolean bgIsColor; |
||||||
|
private int bgColor; |
||||||
|
private float lineMultiplier; |
||||||
|
private float paragraphSize; |
||||||
|
private int pageMode; |
||||||
|
private Boolean hideStatusBar; |
||||||
|
private Boolean hideNavigationBar; |
||||||
|
private String fontPath; |
||||||
|
private int textConvert; |
||||||
|
private int navBarColor; |
||||||
|
private Boolean textBold; |
||||||
|
private Boolean canClickTurn; |
||||||
|
private Boolean canKeyTurn; |
||||||
|
private Boolean readAloudCanKeyTurn; |
||||||
|
private int CPM; |
||||||
|
private Boolean clickAllNext; |
||||||
|
private Boolean showTitle; |
||||||
|
private Boolean showTimeBattery; |
||||||
|
private Boolean showLine; |
||||||
|
private Boolean darkStatusIcon; |
||||||
|
private int indent; |
||||||
|
private int screenTimeOut; |
||||||
|
private int paddingLeft; |
||||||
|
private int paddingTop; |
||||||
|
private int paddingRight; |
||||||
|
private int paddingBottom; |
||||||
|
private int tipPaddingLeft; |
||||||
|
private int tipPaddingTop; |
||||||
|
private int tipPaddingRight; |
||||||
|
private int tipPaddingBottom; |
||||||
|
private float textLetterSpacing; |
||||||
|
private boolean canSelectText; |
||||||
|
public int minCPM = 200; |
||||||
|
public int maxCPM = 2000; |
||||||
|
private int defaultCPM = 500; |
||||||
|
|
||||||
|
private SharedPreferences preferences; |
||||||
|
|
||||||
|
private static ReadBookControl readBookControl; |
||||||
|
|
||||||
|
public static ReadBookControl getInstance() { |
||||||
|
if (readBookControl == null) { |
||||||
|
synchronized (ReadBookControl.class) { |
||||||
|
if (readBookControl == null) { |
||||||
|
readBookControl = new ReadBookControl(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return readBookControl; |
||||||
|
} |
||||||
|
|
||||||
|
private ReadBookControl() { |
||||||
|
preferences = SharedPreUtils.getInstance().getSharedReadable(); |
||||||
|
initTextDrawable(); |
||||||
|
updateReaderSettings(); |
||||||
|
} |
||||||
|
|
||||||
|
public void updateReaderSettings() { |
||||||
|
this.hideStatusBar = preferences.getBoolean("hide_status_bar", false); |
||||||
|
this.hideNavigationBar = preferences.getBoolean("hide_navigation_bar", false); |
||||||
|
this.indent = preferences.getInt("indent", 2); |
||||||
|
this.textSize = preferences.getInt("textSize", 20); |
||||||
|
this.canClickTurn = preferences.getBoolean("canClickTurn", true); |
||||||
|
this.canKeyTurn = preferences.getBoolean("canKeyTurn", true); |
||||||
|
this.readAloudCanKeyTurn = preferences.getBoolean("readAloudCanKeyTurn", false); |
||||||
|
this.lineMultiplier = preferences.getFloat("lineMultiplier", 1); |
||||||
|
this.paragraphSize = preferences.getFloat("paragraphSize", 1); |
||||||
|
this.CPM = preferences.getInt("CPM", defaultCPM) > maxCPM |
||||||
|
? minCPM : preferences.getInt("CPM", defaultCPM); |
||||||
|
this.clickAllNext = preferences.getBoolean("clickAllNext", false); |
||||||
|
this.fontPath = preferences.getString("fontPath", null); |
||||||
|
this.textConvert = preferences.getInt("textConvertInt", 0); |
||||||
|
this.textBold = preferences.getBoolean("textBold", false); |
||||||
|
this.speechRate = preferences.getInt("speechRate", 10); |
||||||
|
this.speechRateFollowSys = preferences.getBoolean("speechRateFollowSys", true); |
||||||
|
this.showTitle = preferences.getBoolean("showTitle", true); |
||||||
|
this.showTimeBattery = preferences.getBoolean("showTimeBattery", true); |
||||||
|
this.showLine = preferences.getBoolean("showLine", true); |
||||||
|
this.screenTimeOut = preferences.getInt("screenTimeOut", 0); |
||||||
|
this.paddingLeft = preferences.getInt("paddingLeft", DEFAULT_MARGIN_WIDTH); |
||||||
|
this.paddingTop = preferences.getInt("paddingTop", 0); |
||||||
|
this.paddingRight = preferences.getInt("paddingRight", DEFAULT_MARGIN_WIDTH); |
||||||
|
this.paddingBottom = preferences.getInt("paddingBottom", 0); |
||||||
|
this.tipPaddingLeft = preferences.getInt("tipPaddingLeft", DEFAULT_MARGIN_WIDTH); |
||||||
|
this.tipPaddingTop = preferences.getInt("tipPaddingTop", 0); |
||||||
|
this.tipPaddingRight = preferences.getInt("tipPaddingRight", DEFAULT_MARGIN_WIDTH); |
||||||
|
this.tipPaddingBottom = preferences.getInt("tipPaddingBottom", 0); |
||||||
|
this.pageMode = preferences.getInt("pageMode", 0); |
||||||
|
this.screenDirection = preferences.getInt("screenDirection", 0); |
||||||
|
this.navBarColor = preferences.getInt("navBarColorInt", 0); |
||||||
|
this.textLetterSpacing = preferences.getFloat("textLetterSpacing", 0); |
||||||
|
this.canSelectText = preferences.getBoolean("canSelectText", false); |
||||||
|
initTextDrawableIndex(); |
||||||
|
} |
||||||
|
|
||||||
|
//阅读背景
|
||||||
|
private void initTextDrawable() { |
||||||
|
if (null == textDrawable) { |
||||||
|
textDrawable = new ArrayList<>(); |
||||||
|
Map<String, Integer> temp1 = new HashMap<>(); |
||||||
|
temp1.put("textColor", Color.parseColor("#3E3D3B")); |
||||||
|
temp1.put("bgIsColor", 1); |
||||||
|
temp1.put("textBackground", Color.parseColor("#F3F3F3")); |
||||||
|
temp1.put("darkStatusIcon", 1); |
||||||
|
textDrawable.add(temp1); |
||||||
|
|
||||||
|
Map<String, Integer> temp2 = new HashMap<>(); |
||||||
|
temp2.put("textColor", Color.parseColor("#5E432E")); |
||||||
|
temp2.put("bgIsColor", 1); |
||||||
|
temp2.put("textBackground", Color.parseColor("#C6BAA1")); |
||||||
|
temp2.put("darkStatusIcon", 1); |
||||||
|
textDrawable.add(temp2); |
||||||
|
|
||||||
|
Map<String, Integer> temp3 = new HashMap<>(); |
||||||
|
temp3.put("textColor", Color.parseColor("#22482C")); |
||||||
|
temp3.put("bgIsColor", 1); |
||||||
|
temp3.put("textBackground", Color.parseColor("#E1F1DA")); |
||||||
|
temp3.put("darkStatusIcon", 1); |
||||||
|
textDrawable.add(temp3); |
||||||
|
|
||||||
|
Map<String, Integer> temp4 = new HashMap<>(); |
||||||
|
temp4.put("textColor", Color.parseColor("#FFFFFF")); |
||||||
|
temp4.put("bgIsColor", 1); |
||||||
|
temp4.put("textBackground", Color.parseColor("#015A86")); |
||||||
|
temp4.put("darkStatusIcon", 0); |
||||||
|
textDrawable.add(temp4); |
||||||
|
|
||||||
|
Map<String, Integer> temp5 = new HashMap<>(); |
||||||
|
temp5.put("textColor", Color.parseColor("#808080")); |
||||||
|
temp5.put("bgIsColor", 1); |
||||||
|
temp5.put("textBackground", Color.parseColor("#000000")); |
||||||
|
temp5.put("darkStatusIcon", 0); |
||||||
|
textDrawable.add(temp5); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void initTextDrawableIndex() { |
||||||
|
if (getIsNightTheme()) { |
||||||
|
textDrawableIndex = preferences.getInt("textDrawableIndexNight", 4); |
||||||
|
} else { |
||||||
|
textDrawableIndex = preferences.getInt("textDrawableIndex", DEFAULT_BG); |
||||||
|
} |
||||||
|
if (textDrawableIndex == -1) { |
||||||
|
textDrawableIndex = DEFAULT_BG; |
||||||
|
} |
||||||
|
initPageStyle(); |
||||||
|
setTextDrawable(); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions") |
||||||
|
private void initPageStyle() { |
||||||
|
int bgCustom = getBgCustom(textDrawableIndex); |
||||||
|
if ((bgCustom == 2 || bgCustom == 3) && getBgPath(textDrawableIndex) != null) { |
||||||
|
bgIsColor = false; |
||||||
|
String bgPath = getBgPath(textDrawableIndex); |
||||||
|
Resources resources = MyApplication.getApplication().getResources(); |
||||||
|
DisplayMetrics dm = resources.getDisplayMetrics(); |
||||||
|
int width = dm.widthPixels; |
||||||
|
int height = dm.heightPixels; |
||||||
|
if (bgCustom == 2) { |
||||||
|
bgBitmap = BitmapUtil.getFitSampleBitmap(bgPath, width, height); |
||||||
|
} else { |
||||||
|
bgBitmap = MeUtils.getFitAssetsSampleBitmap(MyApplication.getApplication().getAssets(), bgPath, width, height); |
||||||
|
} |
||||||
|
if (bgBitmap != null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
} else if (getBgCustom(textDrawableIndex) == 1) { |
||||||
|
bgIsColor = true; |
||||||
|
bgColor = getBgColor(textDrawableIndex); |
||||||
|
return; |
||||||
|
} |
||||||
|
bgIsColor = true; |
||||||
|
bgColor = textDrawable.get(textDrawableIndex).get("textBackground"); |
||||||
|
} |
||||||
|
|
||||||
|
private void setTextDrawable() { |
||||||
|
darkStatusIcon = getDarkStatusIcon(textDrawableIndex); |
||||||
|
textColor = getTextColor(textDrawableIndex); |
||||||
|
} |
||||||
|
|
||||||
|
public int getTextColor(int textDrawableIndex) { |
||||||
|
if (preferences.getInt("textColor" + textDrawableIndex, 0) != 0) { |
||||||
|
return preferences.getInt("textColor" + textDrawableIndex, 0); |
||||||
|
} else { |
||||||
|
return getDefaultTextColor(textDrawableIndex); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setTextColor(int textDrawableIndex, int textColor) { |
||||||
|
preferences.edit() |
||||||
|
.putInt("textColor" + textDrawableIndex, textColor) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions") |
||||||
|
public Drawable getBgDrawable(int textDrawableIndex, Context context, int width, int height) { |
||||||
|
int color; |
||||||
|
try { |
||||||
|
Bitmap bitmap = null; |
||||||
|
switch (getBgCustom(textDrawableIndex)) { |
||||||
|
case 3: |
||||||
|
bitmap = MeUtils.getFitAssetsSampleBitmap(context.getAssets(), getBgPath(textDrawableIndex), width, height); |
||||||
|
if (bitmap != null) { |
||||||
|
return new BitmapDrawable(context.getResources(), bitmap); |
||||||
|
} |
||||||
|
case 2: |
||||||
|
bitmap = BitmapUtil.getFitSampleBitmap(getBgPath(textDrawableIndex), width, height); |
||||||
|
if (bitmap != null) { |
||||||
|
return new BitmapDrawable(context.getResources(), bitmap); |
||||||
|
} |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
color = getBgColor(textDrawableIndex); |
||||||
|
return new ColorDrawable(color); |
||||||
|
} |
||||||
|
if (textDrawable.get(textDrawableIndex).get("bgIsColor") != 0) { |
||||||
|
color = textDrawable.get(textDrawableIndex).get("textBackground"); |
||||||
|
return new ColorDrawable(color); |
||||||
|
} else { |
||||||
|
return getDefaultBgDrawable(textDrawableIndex, context); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
if (textDrawable.get(textDrawableIndex).get("bgIsColor") != 0) { |
||||||
|
color = textDrawable.get(textDrawableIndex).get("textBackground"); |
||||||
|
return new ColorDrawable(color); |
||||||
|
} else { |
||||||
|
return getDefaultBgDrawable(textDrawableIndex, context); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions") |
||||||
|
public Drawable getDefaultBgDrawable(int textDrawableIndex, Context context) { |
||||||
|
if (textDrawable.get(textDrawableIndex).get("bgIsColor") != 0) { |
||||||
|
return new ColorDrawable(textDrawable.get(textDrawableIndex).get("textBackground")); |
||||||
|
} else { |
||||||
|
return context.getResources().getDrawable(getDefaultBg(textDrawableIndex)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public int getBgCustom(int textDrawableIndex) { |
||||||
|
return preferences.getInt("bgCustom" + textDrawableIndex, 0); |
||||||
|
} |
||||||
|
|
||||||
|
public void setBgCustom(int textDrawableIndex, int bgCustom) { |
||||||
|
preferences.edit() |
||||||
|
.putInt("bgCustom" + textDrawableIndex, bgCustom) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getBgPath(int textDrawableIndex) { |
||||||
|
return preferences.getString("bgPath" + textDrawableIndex, null); |
||||||
|
} |
||||||
|
|
||||||
|
public void setBgPath(int textDrawableIndex, String bgUri) { |
||||||
|
preferences.edit() |
||||||
|
.putString("bgPath" + textDrawableIndex, bgUri) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions") |
||||||
|
public int getDefaultTextColor(int textDrawableIndex) { |
||||||
|
return textDrawable.get(textDrawableIndex).get("textColor"); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions") |
||||||
|
private int getDefaultBg(int textDrawableIndex) { |
||||||
|
return textDrawable.get(textDrawableIndex).get("textBackground"); |
||||||
|
} |
||||||
|
|
||||||
|
public int getBgColor(int index) { |
||||||
|
return preferences.getInt("bgColor" + index, Color.parseColor("#1e1e1e")); |
||||||
|
} |
||||||
|
|
||||||
|
public void setBgColor(int index, int bgColor) { |
||||||
|
preferences.edit() |
||||||
|
.putInt("bgColor" + index, bgColor) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean getIsNightTheme() { |
||||||
|
return MyApplication.getApplication().isNightTheme(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean getImmersionStatusBar() { |
||||||
|
return preferences.getBoolean("immersionStatusBar", false); |
||||||
|
} |
||||||
|
|
||||||
|
public void setImmersionStatusBar(boolean immersionStatusBar) { |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("immersionStatusBar", immersionStatusBar) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getTextSize() { |
||||||
|
return textSize; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTextSize(int textSize) { |
||||||
|
this.textSize = textSize; |
||||||
|
preferences.edit() |
||||||
|
.putInt("textSize", textSize) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getTextColor() { |
||||||
|
return textColor; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean bgIsColor() { |
||||||
|
return bgIsColor; |
||||||
|
} |
||||||
|
|
||||||
|
public Drawable getTextBackground(Context context) { |
||||||
|
if (bgIsColor) { |
||||||
|
return new ColorDrawable(bgColor); |
||||||
|
} |
||||||
|
return new BitmapDrawable(context.getResources(), bgBitmap); |
||||||
|
} |
||||||
|
|
||||||
|
public int getBgColor() { |
||||||
|
return bgColor; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean bgBitmapIsNull() { |
||||||
|
return bgBitmap == null || bgBitmap.isRecycled(); |
||||||
|
} |
||||||
|
|
||||||
|
public Bitmap getBgBitmap() { |
||||||
|
return bgBitmap.copy(Bitmap.Config.ARGB_8888, true); |
||||||
|
} |
||||||
|
|
||||||
|
public int getTextDrawableIndex() { |
||||||
|
return textDrawableIndex; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTextDrawableIndex(int textDrawableIndex) { |
||||||
|
this.textDrawableIndex = textDrawableIndex; |
||||||
|
if (getIsNightTheme()) { |
||||||
|
preferences.edit() |
||||||
|
.putInt("textDrawableIndexNight", textDrawableIndex) |
||||||
|
.apply(); |
||||||
|
} else { |
||||||
|
preferences.edit() |
||||||
|
.putInt("textDrawableIndex", textDrawableIndex) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
setTextDrawable(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setTextConvert(int textConvert) { |
||||||
|
this.textConvert = textConvert; |
||||||
|
preferences.edit() |
||||||
|
.putInt("textConvertInt", textConvert) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setNavBarColor(int navBarColor) { |
||||||
|
this.navBarColor = navBarColor; |
||||||
|
preferences.edit() |
||||||
|
.putInt("navBarColorInt", navBarColor) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getNavBarColor() { |
||||||
|
return navBarColor; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void setTextBold(boolean textBold) { |
||||||
|
this.textBold = textBold; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("textBold", textBold) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setReadBookFont(String fontPath) { |
||||||
|
this.fontPath = fontPath; |
||||||
|
preferences.edit() |
||||||
|
.putString("fontPath", fontPath) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getFontPath() { |
||||||
|
return fontPath; |
||||||
|
} |
||||||
|
|
||||||
|
public int getTextConvert() { |
||||||
|
return textConvert == -1 ? 2 : textConvert; |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getTextBold() { |
||||||
|
return textBold; |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getCanKeyTurn(Boolean isPlay) { |
||||||
|
if (!canKeyTurn) { |
||||||
|
return false; |
||||||
|
} else if (readAloudCanKeyTurn) { |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return !isPlay; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getCanKeyTurn() { |
||||||
|
return canKeyTurn; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCanKeyTurn(Boolean canKeyTurn) { |
||||||
|
this.canKeyTurn = canKeyTurn; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("canKeyTurn", canKeyTurn) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getAloudCanKeyTurn() { |
||||||
|
return readAloudCanKeyTurn; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAloudCanKeyTurn(Boolean canAloudKeyTurn) { |
||||||
|
this.readAloudCanKeyTurn = canAloudKeyTurn; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("readAloudCanKeyTurn", canAloudKeyTurn) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getCanClickTurn() { |
||||||
|
return canClickTurn; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCanClickTurn(Boolean canClickTurn) { |
||||||
|
this.canClickTurn = canClickTurn; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("canClickTurn", canClickTurn) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public float getTextLetterSpacing() { |
||||||
|
return textLetterSpacing; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTextLetterSpacing(float textLetterSpacing) { |
||||||
|
this.textLetterSpacing = textLetterSpacing; |
||||||
|
preferences.edit() |
||||||
|
.putFloat("textLetterSpacing", textLetterSpacing) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public float getLineMultiplier() { |
||||||
|
return lineMultiplier; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLineMultiplier(float lineMultiplier) { |
||||||
|
this.lineMultiplier = lineMultiplier; |
||||||
|
preferences.edit() |
||||||
|
.putFloat("lineMultiplier", lineMultiplier) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public float getParagraphSize() { |
||||||
|
return paragraphSize; |
||||||
|
} |
||||||
|
|
||||||
|
public void setParagraphSize(float paragraphSize) { |
||||||
|
this.paragraphSize = paragraphSize; |
||||||
|
preferences.edit() |
||||||
|
.putFloat("paragraphSize", paragraphSize) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getCPM() { |
||||||
|
return CPM; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCPM(int cpm) { |
||||||
|
if (cpm < minCPM || cpm > maxCPM) cpm = defaultCPM; |
||||||
|
this.CPM = cpm; |
||||||
|
preferences.edit() |
||||||
|
.putInt("CPM", cpm) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getClickAllNext() { |
||||||
|
return clickAllNext; |
||||||
|
} |
||||||
|
|
||||||
|
public void setClickAllNext(Boolean clickAllNext) { |
||||||
|
this.clickAllNext = clickAllNext; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("clickAllNext", clickAllNext) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getSpeechRate() { |
||||||
|
return speechRate; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSpeechRate(int speechRate) { |
||||||
|
this.speechRate = speechRate; |
||||||
|
preferences.edit() |
||||||
|
.putInt("speechRate", speechRate) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isSpeechRateFollowSys() { |
||||||
|
return speechRateFollowSys; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSpeechRateFollowSys(boolean speechRateFollowSys) { |
||||||
|
this.speechRateFollowSys = speechRateFollowSys; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("speechRateFollowSys", speechRateFollowSys) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getShowTitle() { |
||||||
|
return showTitle; |
||||||
|
} |
||||||
|
|
||||||
|
public void setShowTitle(Boolean showTitle) { |
||||||
|
this.showTitle = showTitle; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("showTitle", showTitle) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getShowTimeBattery() { |
||||||
|
return showTimeBattery; |
||||||
|
} |
||||||
|
|
||||||
|
public void setShowTimeBattery(Boolean showTimeBattery) { |
||||||
|
this.showTimeBattery = showTimeBattery; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("showTimeBattery", showTimeBattery) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getHideStatusBar() { |
||||||
|
return hideStatusBar; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHideStatusBar(Boolean hideStatusBar) { |
||||||
|
this.hideStatusBar = hideStatusBar; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("hide_status_bar", hideStatusBar) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getToLh() { |
||||||
|
return preferences.getBoolean("toLh", false); |
||||||
|
} |
||||||
|
|
||||||
|
public void setToLh(Boolean toLh) { |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("toLh", toLh) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getHideNavigationBar() { |
||||||
|
return hideNavigationBar; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHideNavigationBar(Boolean hideNavigationBar) { |
||||||
|
this.hideNavigationBar = hideNavigationBar; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("hide_navigation_bar", hideNavigationBar) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getShowLine() { |
||||||
|
return showLine; |
||||||
|
} |
||||||
|
|
||||||
|
public void setShowLine(Boolean showLine) { |
||||||
|
this.showLine = showLine; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("showLine", showLine) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean getDarkStatusIcon() { |
||||||
|
return darkStatusIcon; |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions") |
||||||
|
public boolean getDarkStatusIcon(int textDrawableIndex) { |
||||||
|
return preferences.getBoolean("darkStatusIcon" + textDrawableIndex, textDrawable.get(textDrawableIndex).get("darkStatusIcon") != 0); |
||||||
|
} |
||||||
|
|
||||||
|
public void setDarkStatusIcon(int textDrawableIndex, Boolean darkStatusIcon) { |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("darkStatusIcon" + textDrawableIndex, darkStatusIcon) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getScreenTimeOut() { |
||||||
|
return screenTimeOut; |
||||||
|
} |
||||||
|
|
||||||
|
public void setScreenTimeOut(int screenTimeOut) { |
||||||
|
this.screenTimeOut = screenTimeOut; |
||||||
|
preferences.edit() |
||||||
|
.putInt("screenTimeOut", screenTimeOut) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getPaddingLeft() { |
||||||
|
return paddingLeft; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPaddingLeft(int paddingLeft) { |
||||||
|
this.paddingLeft = paddingLeft; |
||||||
|
preferences.edit() |
||||||
|
.putInt("paddingLeft", paddingLeft) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getPaddingTop() { |
||||||
|
return paddingTop; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPaddingTop(int paddingTop) { |
||||||
|
this.paddingTop = paddingTop; |
||||||
|
preferences.edit() |
||||||
|
.putInt("paddingTop", paddingTop) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getPaddingRight() { |
||||||
|
return paddingRight; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPaddingRight(int paddingRight) { |
||||||
|
this.paddingRight = paddingRight; |
||||||
|
preferences.edit() |
||||||
|
.putInt("paddingRight", paddingRight) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getPaddingBottom() { |
||||||
|
return paddingBottom; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPaddingBottom(int paddingBottom) { |
||||||
|
this.paddingBottom = paddingBottom; |
||||||
|
preferences.edit() |
||||||
|
.putInt("paddingBottom", paddingBottom) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getTipPaddingLeft() { |
||||||
|
return tipPaddingLeft; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTipPaddingLeft(int tipPaddingLeft) { |
||||||
|
this.tipPaddingLeft = tipPaddingLeft; |
||||||
|
preferences.edit() |
||||||
|
.putInt("tipPaddingLeft", tipPaddingLeft) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isCanSelectText() { |
||||||
|
return canSelectText; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCanSelectText(boolean canSelectText) { |
||||||
|
this.canSelectText = canSelectText; |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("canSelectText", canSelectText) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getTipPaddingTop() { |
||||||
|
return tipPaddingTop; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTipPaddingTop(int tipPaddingTop) { |
||||||
|
this.tipPaddingTop = tipPaddingTop; |
||||||
|
preferences.edit() |
||||||
|
.putInt("tipPaddingTop", tipPaddingTop) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getTipPaddingRight() { |
||||||
|
return tipPaddingRight; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTipPaddingRight(int tipPaddingRight) { |
||||||
|
this.tipPaddingRight = tipPaddingRight; |
||||||
|
preferences.edit() |
||||||
|
.putInt("tipPaddingRight", tipPaddingRight) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getTipPaddingBottom() { |
||||||
|
return tipPaddingBottom; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTipPaddingBottom(int tipPaddingBottom) { |
||||||
|
this.tipPaddingBottom = tipPaddingBottom; |
||||||
|
preferences.edit() |
||||||
|
.putInt("tipPaddingBottom", tipPaddingBottom) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getPageMode() { |
||||||
|
return pageMode; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPageMode(int pageMode) { |
||||||
|
this.pageMode = pageMode; |
||||||
|
preferences.edit() |
||||||
|
.putInt("pageMode", pageMode) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getScreenDirection() { |
||||||
|
return screenDirection; |
||||||
|
} |
||||||
|
|
||||||
|
public void setScreenDirection(int screenDirection) { |
||||||
|
this.screenDirection = screenDirection; |
||||||
|
preferences.edit() |
||||||
|
.putInt("screenDirection", screenDirection) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setIndent(int indent) { |
||||||
|
this.indent = indent; |
||||||
|
preferences.edit() |
||||||
|
.putInt("indent", indent) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public int getIndent() { |
||||||
|
return indent; |
||||||
|
} |
||||||
|
|
||||||
|
public int getLight() { |
||||||
|
return preferences.getInt("light", getScreenBrightness()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setLight(int light) { |
||||||
|
preferences.edit() |
||||||
|
.putInt("light", light) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getLightFollowSys() { |
||||||
|
return preferences.getBoolean("lightFollowSys", true); |
||||||
|
} |
||||||
|
|
||||||
|
public void setLightFollowSys(boolean isFollowSys) { |
||||||
|
preferences.edit() |
||||||
|
.putBoolean("lightFollowSys", isFollowSys) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
private int getScreenBrightness() { |
||||||
|
int value = 0; |
||||||
|
ContentResolver cr = MyApplication.getApplication().getContentResolver(); |
||||||
|
try { |
||||||
|
value = Settings.System.getInt(cr, Settings.System.SCREEN_BRIGHTNESS); |
||||||
|
} catch (Settings.SettingNotFoundException ignored) { |
||||||
|
} |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean disableScrollClickTurn() { |
||||||
|
return preferences.getBoolean("disableScrollClickTurn", false); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,318 @@ |
|||||||
|
package xyz.fycz.myreader.entity; |
||||||
|
|
||||||
|
import com.google.gson.Gson; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
import xyz.fycz.myreader.enums.Font; |
||||||
|
import xyz.fycz.myreader.enums.Language; |
||||||
|
import xyz.fycz.myreader.greendao.entity.Book; |
||||||
|
import xyz.fycz.myreader.widget.page.PageMode; |
||||||
|
|
||||||
|
/** |
||||||
|
* 阅读布局 |
||||||
|
*/ |
||||||
|
|
||||||
|
public class ReadStyle implements Serializable { |
||||||
|
|
||||||
|
private static final long serialVersionUID = 2295691803219441757L; |
||||||
|
|
||||||
|
private int readWordSize;//阅读字体大小
|
||||||
|
|
||||||
|
private int brightProgress;//亮度 1- 100
|
||||||
|
|
||||||
|
private boolean brightFollowSystem;//亮度跟随系统
|
||||||
|
|
||||||
|
private Language language;//简繁体
|
||||||
|
|
||||||
|
private Font font;//字体
|
||||||
|
|
||||||
|
private int autoScrollSpeed;//自动滑屏速度
|
||||||
|
|
||||||
|
private PageMode pageMode;//翻页模式
|
||||||
|
|
||||||
|
private boolean isVolumeTurnPage = true;//是否开启音量键翻页
|
||||||
|
|
||||||
|
private int resetScreen = 3;//息屏时间(单位:min,0是不息屏)
|
||||||
|
|
||||||
|
private String localFontName;//本地字体名字
|
||||||
|
|
||||||
|
private boolean isShowStatusBar;//是否显示状态栏
|
||||||
|
|
||||||
|
private boolean alwaysNext;//是否总是翻到下一页
|
||||||
|
|
||||||
|
private int intent;//缩进字符
|
||||||
|
|
||||||
|
private float lineMultiplier;//行间距
|
||||||
|
|
||||||
|
private float paragraphSize;//段间距
|
||||||
|
|
||||||
|
private float textLetterSpacing;//字间距
|
||||||
|
|
||||||
|
private int paddingLeft;//左边距
|
||||||
|
private int paddingTop;//上边距
|
||||||
|
private int paddingRight;//右边距
|
||||||
|
private int paddingBottom;//下边距
|
||||||
|
|
||||||
|
private int composition;//排版选择
|
||||||
|
|
||||||
|
private boolean tightCom;//是否紧凑排版
|
||||||
|
|
||||||
|
private boolean bgIsColor;//背景是否为颜色 不能共用
|
||||||
|
|
||||||
|
private boolean bgIsAssert;//背景是否为assert文件 不能共用
|
||||||
|
|
||||||
|
private int textColor;//文字颜色 不能共用
|
||||||
|
|
||||||
|
private int bgColor;//背景颜色 不能共用
|
||||||
|
|
||||||
|
private String bgPath;//背景图片地址 不能共用
|
||||||
|
|
||||||
|
private boolean protectEye;//开启护眼模式
|
||||||
|
|
||||||
|
private int blueFilterPercent;//蓝光过滤比率
|
||||||
|
|
||||||
|
@Override |
||||||
|
public Object clone() { |
||||||
|
try { |
||||||
|
Gson gson = new Gson(); |
||||||
|
String json = gson.toJson(this); |
||||||
|
return gson.fromJson(json, ReadStyle.class); |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public int getReadWordSize() { |
||||||
|
return readWordSize; |
||||||
|
} |
||||||
|
|
||||||
|
public void setReadWordSize(int readWordSize) { |
||||||
|
this.readWordSize = readWordSize; |
||||||
|
} |
||||||
|
|
||||||
|
public int getBrightProgress() { |
||||||
|
return brightProgress; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBrightProgress(int brightProgress) { |
||||||
|
this.brightProgress = brightProgress; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isBrightFollowSystem() { |
||||||
|
return brightFollowSystem; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBrightFollowSystem(boolean brightFollowSystem) { |
||||||
|
this.brightFollowSystem = brightFollowSystem; |
||||||
|
} |
||||||
|
|
||||||
|
public Language getLanguage() { |
||||||
|
return language; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLanguage(Language language) { |
||||||
|
this.language = language; |
||||||
|
} |
||||||
|
|
||||||
|
public Font getFont() { |
||||||
|
return font; |
||||||
|
} |
||||||
|
|
||||||
|
public void setFont(Font font) { |
||||||
|
this.font = font; |
||||||
|
} |
||||||
|
|
||||||
|
public int getAutoScrollSpeed() { |
||||||
|
return autoScrollSpeed; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAutoScrollSpeed(int autoScrollSpeed) { |
||||||
|
this.autoScrollSpeed = autoScrollSpeed; |
||||||
|
} |
||||||
|
|
||||||
|
public PageMode getPageMode() { |
||||||
|
return pageMode; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPageMode(PageMode pageMode) { |
||||||
|
this.pageMode = pageMode; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isVolumeTurnPage() { |
||||||
|
return isVolumeTurnPage; |
||||||
|
} |
||||||
|
|
||||||
|
public void setVolumeTurnPage(boolean volumeTurnPage) { |
||||||
|
isVolumeTurnPage = volumeTurnPage; |
||||||
|
} |
||||||
|
|
||||||
|
public int getResetScreen() { |
||||||
|
return resetScreen; |
||||||
|
} |
||||||
|
|
||||||
|
public void setResetScreen(int resetScreen) { |
||||||
|
this.resetScreen = resetScreen; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLocalFontName() { |
||||||
|
return localFontName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLocalFontName(String localFontName) { |
||||||
|
this.localFontName = localFontName; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isShowStatusBar() { |
||||||
|
return isShowStatusBar; |
||||||
|
} |
||||||
|
|
||||||
|
public void setShowStatusBar(boolean showStatusBar) { |
||||||
|
isShowStatusBar = showStatusBar; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isAlwaysNext() { |
||||||
|
return alwaysNext; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAlwaysNext(boolean alwaysNext) { |
||||||
|
this.alwaysNext = alwaysNext; |
||||||
|
} |
||||||
|
|
||||||
|
public int getIntent() { |
||||||
|
return intent; |
||||||
|
} |
||||||
|
|
||||||
|
public void setIntent(int intent) { |
||||||
|
this.intent = intent; |
||||||
|
} |
||||||
|
|
||||||
|
public float getLineMultiplier() { |
||||||
|
return lineMultiplier; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLineMultiplier(float lineMultiplier) { |
||||||
|
this.lineMultiplier = lineMultiplier; |
||||||
|
} |
||||||
|
|
||||||
|
public float getParagraphSize() { |
||||||
|
return paragraphSize; |
||||||
|
} |
||||||
|
|
||||||
|
public void setParagraphSize(float paragraphSize) { |
||||||
|
this.paragraphSize = paragraphSize; |
||||||
|
} |
||||||
|
|
||||||
|
public float getTextLetterSpacing() { |
||||||
|
return textLetterSpacing; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTextLetterSpacing(float textLetterSpacing) { |
||||||
|
this.textLetterSpacing = textLetterSpacing; |
||||||
|
} |
||||||
|
|
||||||
|
public int getPaddingLeft() { |
||||||
|
return paddingLeft; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPaddingLeft(int paddingLeft) { |
||||||
|
this.paddingLeft = paddingLeft; |
||||||
|
} |
||||||
|
|
||||||
|
public int getPaddingTop() { |
||||||
|
return paddingTop; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPaddingTop(int paddingTop) { |
||||||
|
this.paddingTop = paddingTop; |
||||||
|
} |
||||||
|
|
||||||
|
public int getPaddingRight() { |
||||||
|
return paddingRight; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPaddingRight(int paddingRight) { |
||||||
|
this.paddingRight = paddingRight; |
||||||
|
} |
||||||
|
|
||||||
|
public int getPaddingBottom() { |
||||||
|
return paddingBottom; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPaddingBottom(int paddingBottom) { |
||||||
|
this.paddingBottom = paddingBottom; |
||||||
|
} |
||||||
|
|
||||||
|
public int getComposition() { |
||||||
|
return composition; |
||||||
|
} |
||||||
|
|
||||||
|
public void setComposition(int composition) { |
||||||
|
this.composition = composition; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isTightCom() { |
||||||
|
return tightCom; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTightCom(boolean tightCom) { |
||||||
|
this.tightCom = tightCom; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean bgIsColor() { |
||||||
|
return bgIsColor; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBgIsColor(boolean bgIsColor) { |
||||||
|
this.bgIsColor = bgIsColor; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean bgIsAssert() { |
||||||
|
return bgIsAssert; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBgIsAssert(boolean bgIsAssert) { |
||||||
|
this.bgIsAssert = bgIsAssert; |
||||||
|
} |
||||||
|
|
||||||
|
public int getTextColor() { |
||||||
|
return textColor; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTextColor(int textColor) { |
||||||
|
this.textColor = textColor; |
||||||
|
} |
||||||
|
|
||||||
|
public int getBgColor() { |
||||||
|
return bgColor; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBgColor(int bgColor) { |
||||||
|
this.bgColor = bgColor; |
||||||
|
} |
||||||
|
|
||||||
|
public String getBgPath() { |
||||||
|
return bgPath; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBgPath(String bgPath) { |
||||||
|
this.bgPath = bgPath; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isProtectEye() { |
||||||
|
return protectEye; |
||||||
|
} |
||||||
|
|
||||||
|
public void setProtectEye(boolean protectEye) { |
||||||
|
this.protectEye = protectEye; |
||||||
|
} |
||||||
|
|
||||||
|
public int getBlueFilterPercent() { |
||||||
|
return blueFilterPercent; |
||||||
|
} |
||||||
|
|
||||||
|
public void setBlueFilterPercent(int blueFilterPercent) { |
||||||
|
this.blueFilterPercent = blueFilterPercent; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,102 @@ |
|||||||
|
package xyz.fycz.myreader.entity; |
||||||
|
|
||||||
|
import xyz.fycz.myreader.greendao.entity.Book; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2020/11/29 19:01 |
||||||
|
*/ |
||||||
|
public class SharedBook { |
||||||
|
private String name; |
||||||
|
private String author; |
||||||
|
private String type; |
||||||
|
private String desc; |
||||||
|
private String imgUrl; |
||||||
|
private String chapterUrl; |
||||||
|
private String source; |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
public void setName(String name) { |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAuthor() { |
||||||
|
return author; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAuthor(String author) { |
||||||
|
this.author = author; |
||||||
|
} |
||||||
|
|
||||||
|
public String getType() { |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
public void setType(String type) { |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDesc() { |
||||||
|
return desc; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDesc(String desc) { |
||||||
|
this.desc = desc; |
||||||
|
} |
||||||
|
|
||||||
|
public String getImgUrl() { |
||||||
|
return imgUrl; |
||||||
|
} |
||||||
|
|
||||||
|
public void setImgUrl(String imgUrl) { |
||||||
|
this.imgUrl = imgUrl; |
||||||
|
} |
||||||
|
|
||||||
|
public String getChapterUrl() { |
||||||
|
return chapterUrl; |
||||||
|
} |
||||||
|
|
||||||
|
public void setChapterUrl(String chapterUrl) { |
||||||
|
this.chapterUrl = chapterUrl; |
||||||
|
} |
||||||
|
|
||||||
|
public String getSource() { |
||||||
|
return source; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSource(String source) { |
||||||
|
this.source = source; |
||||||
|
} |
||||||
|
|
||||||
|
public static SharedBook bookToSharedBook(Book book){ |
||||||
|
int maxDesc = 208; |
||||||
|
String desc = book.getDesc(); |
||||||
|
if (desc.length() > maxDesc){ |
||||||
|
desc = desc.substring(0, maxDesc - 1) + "…"; |
||||||
|
} |
||||||
|
SharedBook sharedBook = new SharedBook(); |
||||||
|
sharedBook.setName(book.getName()); |
||||||
|
sharedBook.setAuthor(book.getAuthor()); |
||||||
|
sharedBook.setType(book.getType()); |
||||||
|
sharedBook.setDesc(desc); |
||||||
|
sharedBook.setImgUrl(book.getImgUrl()); |
||||||
|
sharedBook.setChapterUrl(book.getChapterUrl()); |
||||||
|
sharedBook.setSource(book.getSource()); |
||||||
|
return sharedBook; |
||||||
|
} |
||||||
|
|
||||||
|
public static Book sharedBookToBook(SharedBook sharedBook){ |
||||||
|
Book book = new Book(); |
||||||
|
book.setName(sharedBook.name); |
||||||
|
book.setAuthor(sharedBook.author); |
||||||
|
book.setType(sharedBook.type); |
||||||
|
book.setDesc(sharedBook.desc); |
||||||
|
book.setImgUrl(sharedBook.imgUrl); |
||||||
|
book.setChapterUrl(sharedBook.chapterUrl); |
||||||
|
book.setSource(sharedBook.source); |
||||||
|
return book; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,169 @@ |
|||||||
|
package xyz.fycz.myreader.greendao.entity; |
||||||
|
|
||||||
|
import android.os.Parcel; |
||||||
|
import android.os.Parcelable; |
||||||
|
|
||||||
|
import org.greenrobot.greendao.annotation.Entity; |
||||||
|
import org.greenrobot.greendao.annotation.Generated; |
||||||
|
import org.greenrobot.greendao.annotation.Id; |
||||||
|
import org.greenrobot.greendao.annotation.OrderBy; |
||||||
|
import org.greenrobot.greendao.annotation.Transient; |
||||||
|
|
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by GKF on 2018/2/7. |
||||||
|
* 阅读内容替换规则 |
||||||
|
*/ |
||||||
|
@Entity |
||||||
|
public class ReplaceRuleBean implements Parcelable { |
||||||
|
@Id(autoincrement = true) |
||||||
|
private Long id; |
||||||
|
//描述
|
||||||
|
private String replaceSummary; |
||||||
|
//替换规则
|
||||||
|
private String regex; |
||||||
|
//替换为
|
||||||
|
private String replacement; |
||||||
|
//作用于
|
||||||
|
private String useTo; |
||||||
|
|
||||||
|
private Boolean enable; |
||||||
|
|
||||||
|
private Boolean isRegex; |
||||||
|
|
||||||
|
@OrderBy |
||||||
|
private int serialNumber; |
||||||
|
|
||||||
|
private ReplaceRuleBean(Parcel in) { |
||||||
|
id = in.readLong(); |
||||||
|
regex = in.readString(); |
||||||
|
replacement = in.readString(); |
||||||
|
replaceSummary = in.readString(); |
||||||
|
useTo = in.readString(); |
||||||
|
enable = in.readByte() != 0; |
||||||
|
serialNumber = in.readInt(); |
||||||
|
isRegex = in.readByte() != 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Generated(hash = 1896663649) |
||||||
|
public ReplaceRuleBean(Long id, String replaceSummary, String regex, String replacement, |
||||||
|
String useTo, Boolean enable, Boolean isRegex, int serialNumber) { |
||||||
|
this.id = id; |
||||||
|
this.replaceSummary = replaceSummary; |
||||||
|
this.regex = regex; |
||||||
|
this.replacement = replacement; |
||||||
|
this.useTo = useTo; |
||||||
|
this.enable = enable; |
||||||
|
this.isRegex = isRegex; |
||||||
|
this.serialNumber = serialNumber; |
||||||
|
} |
||||||
|
|
||||||
|
@Generated(hash = 582692869) |
||||||
|
public ReplaceRuleBean() { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void writeToParcel(Parcel parcel, int i) { |
||||||
|
parcel.writeLong(id); |
||||||
|
parcel.writeString(regex); |
||||||
|
parcel.writeString(replacement); |
||||||
|
parcel.writeString(replaceSummary); |
||||||
|
parcel.writeString(useTo); |
||||||
|
parcel.writeByte((byte) (enable ? 1 : 0)); |
||||||
|
parcel.writeInt(serialNumber); |
||||||
|
parcel.writeByte((byte) (isRegex ? 1 : 0)); |
||||||
|
} |
||||||
|
|
||||||
|
@Transient |
||||||
|
public static final Creator<ReplaceRuleBean> CREATOR = new Creator<ReplaceRuleBean>() { |
||||||
|
@Override |
||||||
|
public ReplaceRuleBean createFromParcel(Parcel in) { |
||||||
|
return new ReplaceRuleBean(in); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ReplaceRuleBean[] newArray(int size) { |
||||||
|
return new ReplaceRuleBean[size]; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Override |
||||||
|
public int describeContents() { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
public String getReplaceSummary() { |
||||||
|
return this.replaceSummary; |
||||||
|
} |
||||||
|
|
||||||
|
public void setReplaceSummary(String replaceSummary) { |
||||||
|
this.replaceSummary = replaceSummary; |
||||||
|
} |
||||||
|
|
||||||
|
public String getRegex() { |
||||||
|
return this.regex; |
||||||
|
} |
||||||
|
|
||||||
|
public String getFixedRegex() { |
||||||
|
if (getIsRegex()) |
||||||
|
return this.regex; |
||||||
|
else |
||||||
|
return Pattern.quote(regex); |
||||||
|
} |
||||||
|
|
||||||
|
public void setRegex(String regex) { |
||||||
|
this.regex = regex; |
||||||
|
} |
||||||
|
|
||||||
|
public String getReplacement() { |
||||||
|
return this.replacement; |
||||||
|
} |
||||||
|
|
||||||
|
public void setReplacement(String replacement) { |
||||||
|
this.replacement = replacement; |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getEnable() { |
||||||
|
if (enable == null) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return this.enable; |
||||||
|
} |
||||||
|
|
||||||
|
public void setEnable(Boolean enable) { |
||||||
|
this.enable = enable; |
||||||
|
} |
||||||
|
|
||||||
|
public int getSerialNumber() { |
||||||
|
return this.serialNumber; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSerialNumber(int serialNumber) { |
||||||
|
this.serialNumber = serialNumber; |
||||||
|
} |
||||||
|
|
||||||
|
public Long getId() { |
||||||
|
return this.id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(Long id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUseTo() { |
||||||
|
return this.useTo; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUseTo(String useTo) { |
||||||
|
this.useTo = useTo; |
||||||
|
} |
||||||
|
|
||||||
|
public Boolean getIsRegex() { |
||||||
|
return isRegex == null ? true : isRegex; |
||||||
|
} |
||||||
|
|
||||||
|
public void setIsRegex(Boolean isRegex) { |
||||||
|
this.isRegex = isRegex; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
package xyz.fycz.myreader.model; |
||||||
|
|
||||||
|
import android.text.TextUtils; |
||||||
|
|
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import io.reactivex.Observable; |
||||||
|
import io.reactivex.Single; |
||||||
|
import io.reactivex.SingleOnSubscribe; |
||||||
|
import xyz.fycz.myreader.greendao.GreenDaoManager; |
||||||
|
import xyz.fycz.myreader.greendao.entity.ReplaceRuleBean; |
||||||
|
import xyz.fycz.myreader.greendao.gen.ReplaceRuleBeanDao; |
||||||
|
import xyz.fycz.myreader.util.utils.GsonUtils; |
||||||
|
import xyz.fycz.myreader.util.utils.NetworkUtils; |
||||||
|
import xyz.fycz.myreader.util.utils.RxUtils; |
||||||
|
import xyz.fycz.myreader.util.utils.StringUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by GKF on 2018/2/12. |
||||||
|
* 替换规则管理 |
||||||
|
*/ |
||||||
|
|
||||||
|
public class ReplaceRuleManager { |
||||||
|
private static List<ReplaceRuleBean> replaceRuleBeansEnabled; |
||||||
|
|
||||||
|
public static List<ReplaceRuleBean> getEnabled() { |
||||||
|
if (replaceRuleBeansEnabled == null) { |
||||||
|
replaceRuleBeansEnabled = GreenDaoManager.getDaoSession() |
||||||
|
.getReplaceRuleBeanDao().queryBuilder() |
||||||
|
.where(ReplaceRuleBeanDao.Properties.Enable.eq(true)) |
||||||
|
.orderAsc(ReplaceRuleBeanDao.Properties.SerialNumber) |
||||||
|
.list(); |
||||||
|
} |
||||||
|
return replaceRuleBeansEnabled; |
||||||
|
} |
||||||
|
|
||||||
|
public static Single<List<ReplaceRuleBean>> getAll() { |
||||||
|
return Single.create((SingleOnSubscribe<List<ReplaceRuleBean>>) emitter -> emitter.onSuccess(GreenDaoManager.getDaoSession() |
||||||
|
.getReplaceRuleBeanDao().queryBuilder() |
||||||
|
.orderAsc(ReplaceRuleBeanDao.Properties.SerialNumber) |
||||||
|
.list())).compose(RxUtils::toSimpleSingle); |
||||||
|
} |
||||||
|
|
||||||
|
public static Single<Boolean> saveData(ReplaceRuleBean replaceRuleBean) { |
||||||
|
return Single.create((SingleOnSubscribe<Boolean>) emitter -> { |
||||||
|
if (replaceRuleBean.getSerialNumber() == 0) { |
||||||
|
replaceRuleBean.setSerialNumber((int) (GreenDaoManager.getDaoSession().getReplaceRuleBeanDao().queryBuilder().count() + 1)); |
||||||
|
} |
||||||
|
GreenDaoManager.getDaoSession().getReplaceRuleBeanDao().insertOrReplace(replaceRuleBean); |
||||||
|
refreshDataS(); |
||||||
|
emitter.onSuccess(true); |
||||||
|
}).compose(RxUtils::toSimpleSingle); |
||||||
|
} |
||||||
|
|
||||||
|
public static void delData(ReplaceRuleBean replaceRuleBean) { |
||||||
|
GreenDaoManager.getDaoSession().getReplaceRuleBeanDao().delete(replaceRuleBean); |
||||||
|
refreshDataS(); |
||||||
|
} |
||||||
|
|
||||||
|
public static void addDataS(List<ReplaceRuleBean> replaceRuleBeans) { |
||||||
|
if (replaceRuleBeans != null && replaceRuleBeans.size() > 0) { |
||||||
|
GreenDaoManager.getDaoSession().getReplaceRuleBeanDao().insertOrReplaceInTx(replaceRuleBeans); |
||||||
|
refreshDataS(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void delDataS(List<ReplaceRuleBean> replaceRuleBeans) { |
||||||
|
for (ReplaceRuleBean replaceRuleBean : replaceRuleBeans) { |
||||||
|
GreenDaoManager.getDaoSession().getReplaceRuleBeanDao().delete(replaceRuleBean); |
||||||
|
} |
||||||
|
refreshDataS(); |
||||||
|
} |
||||||
|
|
||||||
|
private static void refreshDataS() { |
||||||
|
replaceRuleBeansEnabled = GreenDaoManager.getDaoSession() |
||||||
|
.getReplaceRuleBeanDao().queryBuilder() |
||||||
|
.where(ReplaceRuleBeanDao.Properties.Enable.eq(true)) |
||||||
|
.orderAsc(ReplaceRuleBeanDao.Properties.SerialNumber) |
||||||
|
.list(); |
||||||
|
} |
||||||
|
|
||||||
|
public static Observable<Boolean> importReplaceRule(String text) { |
||||||
|
if (TextUtils.isEmpty(text)) return null; |
||||||
|
text = text.trim(); |
||||||
|
if (text.length() == 0) return null; |
||||||
|
if (StringUtils.isJsonType(text)) { |
||||||
|
return importReplaceRuleO(text) |
||||||
|
.compose(RxUtils::toSimpleSingle); |
||||||
|
} |
||||||
|
/*if (NetworkUtils.isUrl(text)) { |
||||||
|
return BaseModelImpl.getInstance().getRetrofitString(StringUtils.getBaseUrl(text), "utf-8") |
||||||
|
.create(IHttpGetApi.class) |
||||||
|
.get(text, AnalyzeHeaders.getMap(null)) |
||||||
|
.flatMap(rsp -> importReplaceRuleO(rsp.body())) |
||||||
|
.compose(RxUtils::toSimpleSingle); |
||||||
|
}*/ |
||||||
|
return Observable.error(new Exception("不是Json或Url格式")); |
||||||
|
} |
||||||
|
|
||||||
|
private static Observable<Boolean> importReplaceRuleO(String json) { |
||||||
|
return Observable.create(e -> { |
||||||
|
try { |
||||||
|
List<ReplaceRuleBean> replaceRuleBeans = GsonUtils.parseJArray(json, ReplaceRuleBean.class); |
||||||
|
addDataS(replaceRuleBeans); |
||||||
|
e.onNext(true); |
||||||
|
} catch (Exception e1) { |
||||||
|
e1.printStackTrace(); |
||||||
|
e.onNext(false); |
||||||
|
} |
||||||
|
e.onComplete(); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,333 @@ |
|||||||
|
package xyz.fycz.myreader.model.backup; |
||||||
|
|
||||||
|
import io.reactivex.annotations.NonNull; |
||||||
|
import xyz.fycz.myreader.application.MyApplication; |
||||||
|
import xyz.fycz.myreader.model.storage.Backup; |
||||||
|
import xyz.fycz.myreader.model.storage.Restore; |
||||||
|
import xyz.fycz.myreader.webapi.callback.ResultCallback; |
||||||
|
import xyz.fycz.myreader.common.APPCONST; |
||||||
|
import xyz.fycz.myreader.common.URLCONST; |
||||||
|
import xyz.fycz.myreader.util.*; |
||||||
|
import xyz.fycz.myreader.util.utils.FileUtils; |
||||||
|
|
||||||
|
import java.io.*; |
||||||
|
import java.net.HttpURLConnection; |
||||||
|
import java.net.URL; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2020/4/26 11:03 |
||||||
|
*/ |
||||||
|
public class UserService { |
||||||
|
/** |
||||||
|
* 登录 |
||||||
|
* @param userLoginInfo 用户名输入的用户名和密码等登录信息 |
||||||
|
* @return 是否成功登录 |
||||||
|
*/ |
||||||
|
public static void login(final Map<String, String> userLoginInfo, final ResultCallback resultCallback) { |
||||||
|
MyApplication.getApplication().newThread(() -> { |
||||||
|
HttpURLConnection conn = null; |
||||||
|
try { |
||||||
|
URL url = new URL(URLCONST.APP_WEB_URL + "login"); |
||||||
|
conn = (HttpURLConnection) url.openConnection(); |
||||||
|
conn.setRequestMethod("POST"); |
||||||
|
conn.setConnectTimeout(60 * 1000); |
||||||
|
conn.setReadTimeout(60 * 1000); |
||||||
|
conn.setDoInput(true); |
||||||
|
conn.setDoOutput(true); |
||||||
|
String params = "username=" + userLoginInfo.get("loginName") + |
||||||
|
"&password=" + userLoginInfo.get("loginPwd") + makeSignalParam(); |
||||||
|
// 获取URLConnection对象对应的输出流
|
||||||
|
PrintWriter out = new PrintWriter(conn.getOutputStream()); |
||||||
|
// 发送请求参数
|
||||||
|
out.print(params); |
||||||
|
// flush输出流的缓冲
|
||||||
|
out.flush(); |
||||||
|
InputStream in = conn.getInputStream(); |
||||||
|
BufferedReader bw = new BufferedReader(new InputStreamReader(in, "utf-8")); |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
String line = bw.readLine(); |
||||||
|
while (line != null) { |
||||||
|
sb.append(line); |
||||||
|
line = bw.readLine(); |
||||||
|
} |
||||||
|
resultCallback.onFinish(sb.toString(), 1); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
resultCallback.onError(e); |
||||||
|
}finally { |
||||||
|
if (conn != null) { |
||||||
|
conn.disconnect(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public static void register(final Map<String, String> userRegisterInfo, final ResultCallback resultCallback) { |
||||||
|
MyApplication.getApplication().newThread(() -> { |
||||||
|
HttpURLConnection conn = null; |
||||||
|
try { |
||||||
|
URL url = new URL(URLCONST.APP_WEB_URL + "reg"); |
||||||
|
conn = (HttpURLConnection) url.openConnection(); |
||||||
|
conn.setRequestMethod("POST"); |
||||||
|
conn.setDoInput(true); |
||||||
|
conn.setDoOutput(true); |
||||||
|
String params = "username=" + userRegisterInfo.get("username") + "&password=" + |
||||||
|
CyptoUtils.encode(APPCONST.KEY, userRegisterInfo.get("password")) + "&key=" + |
||||||
|
CyptoUtils.encode(APPCONST.KEY, APPCONST.publicKey) + makeSignalParam(); |
||||||
|
// 获取URLConnection对象对应的输出流
|
||||||
|
PrintWriter out = new PrintWriter(conn.getOutputStream()); |
||||||
|
// 发送请求参数
|
||||||
|
out.print(params); |
||||||
|
// flush输出流的缓冲
|
||||||
|
out.flush(); |
||||||
|
BufferedReader bw = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
String line = bw.readLine(); |
||||||
|
while (line != null) { |
||||||
|
sb.append(line); |
||||||
|
line = bw.readLine(); |
||||||
|
} |
||||||
|
resultCallback.onFinish(sb.toString(), 1); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
resultCallback.onError(e); |
||||||
|
} finally { |
||||||
|
if (conn != null) { |
||||||
|
conn.disconnect(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 写配置 |
||||||
|
* @param userLoginInfo |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static boolean writeConfig(Map<String,String> userLoginInfo){ |
||||||
|
FileOutputStream fos = null; |
||||||
|
try { |
||||||
|
fos = MyApplication.getApplication().openFileOutput("userConfig.fy", MyApplication.getApplication().MODE_PRIVATE); |
||||||
|
String userInfo = "username='" + userLoginInfo.get("loginName") + "',\npassword='" + userLoginInfo.get("loginPwd") + "'"; |
||||||
|
byte[] bs = userInfo.getBytes(); |
||||||
|
fos.write(bs); |
||||||
|
//写完后一定要刷新
|
||||||
|
fos.flush(); |
||||||
|
return true; |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
return false; |
||||||
|
} finally { |
||||||
|
IOUtils.close(fos); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 读配置 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Map<String,String> readConfig(){ |
||||||
|
File file = MyApplication.getApplication().getFileStreamPath("userConfig.fy"); |
||||||
|
if (!file.exists()){ |
||||||
|
return null; |
||||||
|
} |
||||||
|
BufferedReader br = null; |
||||||
|
try { |
||||||
|
br = new BufferedReader(new FileReader(file)); |
||||||
|
String tem; |
||||||
|
StringBuilder config = new StringBuilder(); |
||||||
|
while ((tem = br.readLine()) != null){ |
||||||
|
config.append(tem); |
||||||
|
} |
||||||
|
String[] user = config.toString().split(","); |
||||||
|
String userName = user[0].substring(user[0].indexOf("'") + 1, user[0].lastIndexOf("'")); |
||||||
|
String password = user[1].substring(user[1].indexOf("'") + 1, user[1].lastIndexOf("'")); |
||||||
|
Map<String,String> userInfo = new HashMap<>(); |
||||||
|
userInfo.put("userName", userName); |
||||||
|
userInfo.put("password", password); |
||||||
|
return userInfo; |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
}finally { |
||||||
|
IOUtils.close(br); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public static void writeUsername(String username){ |
||||||
|
File file = FileUtils.getFile(APPCONST.QQ_DATA_DIR + "user"); |
||||||
|
BufferedWriter bw = null; |
||||||
|
try { |
||||||
|
bw = new BufferedWriter(new FileWriter(file)); |
||||||
|
bw.write(username); |
||||||
|
bw.flush(); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
}finally { |
||||||
|
IOUtils.close(bw); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static String readUsername(){ |
||||||
|
File file = new File(APPCONST.QQ_DATA_DIR + "user"); |
||||||
|
if (!file.exists()){ |
||||||
|
return ""; |
||||||
|
} |
||||||
|
BufferedReader br = null; |
||||||
|
try { |
||||||
|
br = new BufferedReader(new FileReader(file)); |
||||||
|
return br.readLine(); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
return ""; |
||||||
|
} finally { |
||||||
|
IOUtils.close(br); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 网络备份 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static void webBackup(ResultCallback rc){ |
||||||
|
Map<String,String> userInfo = readConfig(); |
||||||
|
if (userInfo == null){ |
||||||
|
rc.onFinish(false, 0); |
||||||
|
} |
||||||
|
Backup.INSTANCE.backup(MyApplication.getmContext(), APPCONST.FILE_DIR + "webBackup/", new Backup.CallBack() { |
||||||
|
@Override |
||||||
|
public void backupSuccess() { |
||||||
|
MyApplication.getApplication().newThread(() ->{ |
||||||
|
File inputFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup"); |
||||||
|
if (!inputFile.exists()) { |
||||||
|
rc.onFinish(false, 0); |
||||||
|
} |
||||||
|
File zipFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup.zip"); |
||||||
|
FileInputStream fis = null; |
||||||
|
HttpURLConnection conn = null; |
||||||
|
try { |
||||||
|
//压缩文件
|
||||||
|
ZipUtils.zipFile(inputFile, zipFile); |
||||||
|
fis = new FileInputStream(zipFile); |
||||||
|
URL url = new URL(URLCONST.APP_WEB_URL + "bak?username=" + userInfo.get("userName") + |
||||||
|
makeSignalParam()); |
||||||
|
conn = (HttpURLConnection) url.openConnection(); |
||||||
|
conn.setRequestMethod("POST"); |
||||||
|
conn.setRequestProperty("Content-type", "multipart/form-data"); |
||||||
|
conn.setDoInput(true); |
||||||
|
conn.setDoOutput(true); |
||||||
|
OutputStream out = conn.getOutputStream(); |
||||||
|
byte[] bytes = new byte[1024]; |
||||||
|
int len = -1; |
||||||
|
while ((len = fis.read(bytes)) != -1){ |
||||||
|
out.write(bytes, 0, len); |
||||||
|
} |
||||||
|
out.flush(); |
||||||
|
zipFile.delete(); |
||||||
|
BufferedReader bw = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
String line = bw.readLine(); |
||||||
|
while (line != null) { |
||||||
|
sb.append(line); |
||||||
|
line = bw.readLine(); |
||||||
|
} |
||||||
|
String[] info = sb.toString().split(":"); |
||||||
|
int code = Integer.parseInt(info[0].trim()); |
||||||
|
rc.onFinish(code == 104, 0); |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
rc.onError(e); |
||||||
|
} finally { |
||||||
|
IOUtils.close(fis); |
||||||
|
if (conn != null) { |
||||||
|
conn.disconnect(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void backupError(@NonNull String msg) { |
||||||
|
ToastUtils.showError(msg); |
||||||
|
rc.onFinish(false, 0); |
||||||
|
} |
||||||
|
}, false); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 网络恢复 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static void webRestore(ResultCallback rc){ |
||||||
|
Map<String,String> userInfo = readConfig(); |
||||||
|
if (userInfo == null){ |
||||||
|
rc.onFinish(false, 0); |
||||||
|
} |
||||||
|
FileOutputStream fos = null; |
||||||
|
File zipFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup.zip"); |
||||||
|
HttpURLConnection conn = null; |
||||||
|
try { |
||||||
|
URL url = new URL(URLCONST.APP_WEB_URL + "ret?username=" + userInfo.get("userName") + |
||||||
|
makeSignalParam()); |
||||||
|
conn = (HttpURLConnection) url.openConnection(); |
||||||
|
conn.setRequestMethod("POST"); |
||||||
|
conn.setDoInput(true); |
||||||
|
InputStream is = conn.getInputStream(); |
||||||
|
fos = new FileOutputStream(zipFile); |
||||||
|
//一边读,一边写
|
||||||
|
byte[] bytes = new byte[512]; |
||||||
|
int readCount = 0; |
||||||
|
while ((readCount = is.read(bytes)) != -1) { |
||||||
|
fos.write(bytes,0, readCount); |
||||||
|
} |
||||||
|
//刷新,输出流一定要刷新
|
||||||
|
fos.flush(); |
||||||
|
if (zipFile.length() == 0){ |
||||||
|
zipFile.delete(); |
||||||
|
rc.onFinish(false, 0); |
||||||
|
} |
||||||
|
ZipUtils.unzipFile(zipFile.getAbsolutePath(), APPCONST.FILE_DIR); |
||||||
|
Restore.INSTANCE.restore(APPCONST.FILE_DIR + "webBackup/", new Restore.CallBack() { |
||||||
|
@Override |
||||||
|
public void restoreSuccess() { |
||||||
|
zipFile.delete(); |
||||||
|
rc.onFinish(true, 0); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void restoreError(@NonNull String msg) { |
||||||
|
ToastUtils.showError(msg); |
||||||
|
rc.onFinish(false, 0); |
||||||
|
} |
||||||
|
}); |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
rc.onError(e); |
||||||
|
}finally { |
||||||
|
IOUtils.close(fos); |
||||||
|
if (conn != null) { |
||||||
|
conn.disconnect(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private static String makeSignalParam(){ |
||||||
|
return "&signal=" + AppInfoUtils.getSingInfo(MyApplication.getmContext(), |
||||||
|
MyApplication.getApplication().getPackageName(), AppInfoUtils.SHA1); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 判断是否登录 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static boolean isLogin(){ |
||||||
|
File file = MyApplication.getApplication().getFileStreamPath("userConfig.fy"); |
||||||
|
return file.exists(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,231 @@ |
|||||||
|
package xyz.fycz.myreader.ui.activity; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.app.Activity; |
||||||
|
import android.app.ProgressDialog; |
||||||
|
import android.content.Intent; |
||||||
|
import android.graphics.Bitmap; |
||||||
|
import android.os.Bundle; |
||||||
|
import android.os.Handler; |
||||||
|
import android.os.Message; |
||||||
|
import android.text.Editable; |
||||||
|
import android.text.TextWatcher; |
||||||
|
import android.view.MotionEvent; |
||||||
|
import android.view.View; |
||||||
|
import android.view.inputmethod.InputMethodManager; |
||||||
|
import android.widget.Button; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
import butterknife.BindView; |
||||||
|
import com.google.android.material.textfield.TextInputLayout; |
||||||
|
import xyz.fycz.myreader.R; |
||||||
|
import xyz.fycz.myreader.model.backup.UserService; |
||||||
|
import xyz.fycz.myreader.base.BaseActivity; |
||||||
|
import xyz.fycz.myreader.webapi.callback.ResultCallback; |
||||||
|
import xyz.fycz.myreader.common.APPCONST; |
||||||
|
import xyz.fycz.myreader.ui.dialog.DialogCreator; |
||||||
|
import xyz.fycz.myreader.util.CodeUtil; |
||||||
|
import xyz.fycz.myreader.util.CyptoUtils; |
||||||
|
import xyz.fycz.myreader.util.ToastUtils; |
||||||
|
import xyz.fycz.myreader.util.utils.NetworkUtils; |
||||||
|
import xyz.fycz.myreader.util.utils.StringUtils; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2020/9/18 22:27 |
||||||
|
*/ |
||||||
|
public class LoginActivity extends BaseActivity implements TextWatcher { |
||||||
|
@BindView(R.id.et_user) |
||||||
|
TextInputLayout user; |
||||||
|
@BindView(R.id.et_password) |
||||||
|
TextInputLayout password; |
||||||
|
@BindView(R.id.bt_login) |
||||||
|
Button loginBtn; |
||||||
|
@BindView(R.id.tv_register) |
||||||
|
TextView tvRegister; |
||||||
|
@BindView(R.id.et_captcha) |
||||||
|
TextInputLayout etCaptcha; |
||||||
|
@BindView(R.id.iv_captcha) |
||||||
|
ImageView ivCaptcha; |
||||||
|
|
||||||
|
private String code; |
||||||
|
|
||||||
|
@SuppressLint("HandlerLeak") |
||||||
|
private Handler mHandler = new Handler() { |
||||||
|
@SuppressLint("HandlerLeak") |
||||||
|
@Override |
||||||
|
public void handleMessage(Message msg) { |
||||||
|
switch (msg.what) { |
||||||
|
case 1: |
||||||
|
loginBtn.setEnabled(true); |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
createCaptcha(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getContentId() { |
||||||
|
return R.layout.activity_login; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void setUpToolbar(Toolbar toolbar) { |
||||||
|
super.setUpToolbar(toolbar); |
||||||
|
setStatusBarColor(R.color.colorPrimary, true); |
||||||
|
getSupportActionBar().setTitle("登录"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initData(Bundle savedInstanceState) { |
||||||
|
super.initData(savedInstanceState); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initWidget() { |
||||||
|
super.initWidget(); |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(2)); |
||||||
|
String username = UserService.readUsername(); |
||||||
|
user.getEditText().setText(username); |
||||||
|
user.getEditText().requestFocus(username.length()); |
||||||
|
//监听内容改变 -> 控制按钮的点击状态
|
||||||
|
user.getEditText().addTextChangedListener(this); |
||||||
|
password.getEditText().addTextChangedListener(this); |
||||||
|
etCaptcha.getEditText().addTextChangedListener(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initClick() { |
||||||
|
super.initClick(); |
||||||
|
ivCaptcha.setOnClickListener(v -> mHandler.sendMessage(mHandler.obtainMessage(2))); |
||||||
|
|
||||||
|
loginBtn.setOnClickListener(v -> { |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(2)); |
||||||
|
if (!code.toLowerCase().equals(etCaptcha.getEditText().getText().toString().toLowerCase())){ |
||||||
|
DialogCreator.createTipDialog(this, "验证码错误!"); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (!NetworkUtils.isNetWorkAvailable()) { |
||||||
|
ToastUtils.showError("无网络连接!"); |
||||||
|
return; |
||||||
|
} |
||||||
|
ProgressDialog dialog = DialogCreator.createProgressDialog(this, null, "正在登陆..."); |
||||||
|
loginBtn.setEnabled(false); |
||||||
|
final String loginName = user.getEditText().getText().toString().trim(); |
||||||
|
String loginPwd = password.getEditText().getText().toString(); |
||||||
|
final Map<String, String> userLoginInfo = new HashMap<>(); |
||||||
|
userLoginInfo.put("loginName", loginName); |
||||||
|
userLoginInfo.put("loginPwd", CyptoUtils.encode(APPCONST.KEY, loginPwd)); |
||||||
|
//验证用户名和密码
|
||||||
|
UserService.login(userLoginInfo, new ResultCallback() { |
||||||
|
@Override |
||||||
|
public void onFinish(Object o, int code) { |
||||||
|
String result = (String) o; |
||||||
|
String[] info = result.split(":"); |
||||||
|
int resultCode = Integer.parseInt(info[0].trim()); |
||||||
|
String resultName = info[1].trim(); |
||||||
|
//最后输出结果
|
||||||
|
if (resultCode == 102) { |
||||||
|
UserService.writeConfig(userLoginInfo); |
||||||
|
UserService.writeUsername(loginName); |
||||||
|
Intent intent = new Intent(); |
||||||
|
intent.putExtra("isLogin", true); |
||||||
|
setResult(Activity.RESULT_OK, intent); |
||||||
|
finish(); |
||||||
|
ToastUtils.showSuccess(resultName); |
||||||
|
} else { |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(1)); |
||||||
|
dialog.dismiss(); |
||||||
|
ToastUtils.showWarring(resultName); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onError(Exception e) { |
||||||
|
ToastUtils.showError("登录失败\n" + e.getLocalizedMessage()); |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(1)); |
||||||
|
dialog.dismiss(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
tvRegister.setOnClickListener(v -> { |
||||||
|
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class); |
||||||
|
startActivity(intent); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public void createCaptcha() { |
||||||
|
code = CodeUtil.getInstance().createCode(); |
||||||
|
Bitmap codeBitmap = CodeUtil.getInstance().createBitmap(code); |
||||||
|
ivCaptcha.setImageBitmap(codeBitmap); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 当有控件获得焦点focus 自动弹出键盘 |
||||||
|
* 1. 点击软键盘的enter键 自动收回键盘 |
||||||
|
* 2. 代码控制 InputMethodManager |
||||||
|
* requestFocus |
||||||
|
* showSoftInput:显示键盘 必须先让这个view成为焦点requestFocus |
||||||
|
* |
||||||
|
* hideSoftInputFromWindow 隐藏键盘 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public boolean onTouchEvent(MotionEvent event) { |
||||||
|
if (event.getAction() == MotionEvent.ACTION_DOWN){ |
||||||
|
//隐藏键盘
|
||||||
|
//1.获取系统输入的管理器
|
||||||
|
InputMethodManager inputManager = |
||||||
|
(InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); |
||||||
|
|
||||||
|
//2.隐藏键盘
|
||||||
|
inputManager.hideSoftInputFromWindow(user.getWindowToken(),0); |
||||||
|
|
||||||
|
//3.取消焦点
|
||||||
|
View focusView = getCurrentFocus(); |
||||||
|
if (focusView != null) { |
||||||
|
focusView.clearFocus(); //取消焦点
|
||||||
|
} |
||||||
|
|
||||||
|
//getCurrentFocus().clearFocus();
|
||||||
|
|
||||||
|
//focusView.requestFocus();//请求焦点
|
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void afterTextChanged(Editable s) { |
||||||
|
//禁止输入中文
|
||||||
|
StringUtils.isNotChinese(s); |
||||||
|
//判断两个输入框是否有内容
|
||||||
|
if (user.getEditText().getText().toString().length() > 0 && |
||||||
|
password.getEditText().getText().toString().length() > 0 && |
||||||
|
etCaptcha.getEditText().getText().toString().length() > 0){ |
||||||
|
//按钮可以点击
|
||||||
|
loginBtn.setEnabled(true); |
||||||
|
}else{ |
||||||
|
//按钮不能点击
|
||||||
|
loginBtn.setEnabled(false); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,261 @@ |
|||||||
|
package xyz.fycz.myreader.ui.activity; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
import android.content.Intent; |
||||||
|
import android.content.pm.PackageManager; |
||||||
|
import android.graphics.Bitmap; |
||||||
|
import android.graphics.BitmapFactory; |
||||||
|
import android.os.Bundle; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.Menu; |
||||||
|
import android.view.MenuItem; |
||||||
|
import android.view.View; |
||||||
|
import android.view.animation.Animation; |
||||||
|
import android.view.animation.AnimationUtils; |
||||||
|
import android.widget.LinearLayout; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
import androidx.core.app.ActivityCompat; |
||||||
|
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton; |
||||||
|
|
||||||
|
import java.util.Objects; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import cn.bingoogolapple.qrcode.core.QRCodeView; |
||||||
|
import cn.bingoogolapple.qrcode.zxing.ZXingView; |
||||||
|
import io.reactivex.Single; |
||||||
|
import io.reactivex.SingleOnSubscribe; |
||||||
|
import xyz.fycz.myreader.R; |
||||||
|
import xyz.fycz.myreader.base.BaseActivity; |
||||||
|
import xyz.fycz.myreader.base.observer.MySingleObserver; |
||||||
|
import xyz.fycz.myreader.util.PermissionsChecker; |
||||||
|
import xyz.fycz.myreader.util.StringHelper; |
||||||
|
import xyz.fycz.myreader.util.ToastUtils; |
||||||
|
import xyz.fycz.myreader.util.utils.RxUtils; |
||||||
|
|
||||||
|
import static xyz.fycz.myreader.util.UriFileUtil.getPath; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2020/11/30 8:31 |
||||||
|
*/ |
||||||
|
|
||||||
|
public class QRCodeScanActivity extends BaseActivity implements QRCodeView.Delegate { |
||||||
|
|
||||||
|
@BindView(R.id.zxingview) |
||||||
|
ZXingView zxingview; |
||||||
|
@BindView(R.id.toolbar) |
||||||
|
Toolbar toolbar; |
||||||
|
@BindView(R.id.ll_flashlight) |
||||||
|
LinearLayout llFlashLight; |
||||||
|
@BindView(R.id.fab_flashlight) |
||||||
|
FloatingActionButton fabFlashlight; |
||||||
|
@BindView(R.id.tv_flashlight) |
||||||
|
TextView tvFlashlight; |
||||||
|
|
||||||
|
private final int REQUEST_QR_IMAGE = 202; |
||||||
|
private static final String CAMERA = "android.permission.CAMERA"; |
||||||
|
private static final int PERMISSIONS_REQUEST_CAMERA = 101; |
||||||
|
private boolean flashlightIsOpen; |
||||||
|
private boolean needScale = true; |
||||||
|
private String picPath; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getContentId() { |
||||||
|
return R.layout.activity_qrcode_capture; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected void setUpToolbar(Toolbar toolbar) { |
||||||
|
super.setUpToolbar(toolbar); |
||||||
|
setStatusBarColor(R.color.colorPrimary, true); |
||||||
|
getSupportActionBar().setTitle("扫一扫"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 数据初始化 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
protected void initData(Bundle savedInstanceState) { |
||||||
|
zxingview.setDelegate(this); |
||||||
|
fabFlashlight.setOnClickListener(view -> { |
||||||
|
if (flashlightIsOpen) { |
||||||
|
flashlightIsOpen = false; |
||||||
|
zxingview.closeFlashlight(); |
||||||
|
tvFlashlight.setText(getString(R.string.light_contact)); |
||||||
|
} else { |
||||||
|
flashlightIsOpen = true; |
||||||
|
zxingview.openFlashlight(); |
||||||
|
tvFlashlight.setText(getString(R.string.close_contact)); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onStart() { |
||||||
|
super.onStart(); |
||||||
|
startCamera(); |
||||||
|
} |
||||||
|
|
||||||
|
private void startCamera() { |
||||||
|
requestPermission(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onStop() { |
||||||
|
zxingview.stopCamera(); // 关闭摄像头预览,并且隐藏扫描框
|
||||||
|
super.onStop(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onDestroy() { |
||||||
|
zxingview.onDestroy(); // 销毁二维码扫描控件
|
||||||
|
super.onDestroy(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onScanQRCodeSuccess(String result) { |
||||||
|
Log.d("onScanQRCodeSuccess", needScale + ""); |
||||||
|
if (result == null) { |
||||||
|
if (!needScale){ |
||||||
|
needScale = true; |
||||||
|
if (StringHelper.isEmpty(picPath)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
scanFromPath(picPath); |
||||||
|
}else { |
||||||
|
ToastUtils.showError("二维码扫描失败"); |
||||||
|
} |
||||||
|
}else { |
||||||
|
Intent intent = new Intent(); |
||||||
|
Log.d("result", result); |
||||||
|
intent.putExtra("result", result); |
||||||
|
setResult(RESULT_OK, intent); |
||||||
|
finish(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onCameraAmbientBrightnessChanged(boolean isDark) { |
||||||
|
if (isDark){ |
||||||
|
llFlashLight.setVisibility(View.VISIBLE); |
||||||
|
}else { |
||||||
|
if (!flashlightIsOpen) { |
||||||
|
llFlashLight.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onScanQRCodeOpenCameraError() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private void startScan() { |
||||||
|
zxingview.setVisibility(View.VISIBLE); |
||||||
|
zxingview.startSpotAndShowRect(); // 显示扫描框,并开始识别
|
||||||
|
} |
||||||
|
|
||||||
|
private void requestPermission() { |
||||||
|
//获取读取和写入SD卡的权限
|
||||||
|
if (new PermissionsChecker(this).lacksPermissions(CAMERA)) { |
||||||
|
ActivityCompat.requestPermissions(this, new String[]{CAMERA}, PERMISSIONS_REQUEST_CAMERA); |
||||||
|
} else { |
||||||
|
startScan(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { |
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults); |
||||||
|
switch (requestCode) { |
||||||
|
case PERMISSIONS_REQUEST_CAMERA: { |
||||||
|
// 如果取消权限,则返回的值为0
|
||||||
|
if (grantResults.length > 0 |
||||||
|
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { |
||||||
|
//申请权限成功
|
||||||
|
startScan(); |
||||||
|
} else { |
||||||
|
//申请权限失败
|
||||||
|
finish(); |
||||||
|
ToastUtils.showWarring("请给予相机权限,否则无法进行扫码!"); |
||||||
|
} |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 添加菜单
|
||||||
|
@Override |
||||||
|
public boolean onCreateOptionsMenu(Menu menu) { |
||||||
|
getMenuInflater().inflate(R.menu.menu_qr_code_scan, menu); |
||||||
|
return super.onCreateOptionsMenu(menu); |
||||||
|
} |
||||||
|
|
||||||
|
//菜单
|
||||||
|
@Override |
||||||
|
public boolean onOptionsItemSelected(MenuItem item) { |
||||||
|
int id = item.getItemId(); |
||||||
|
switch (id) { |
||||||
|
case R.id.action_choose_from_gallery: |
||||||
|
chooseFromGallery(); |
||||||
|
break; |
||||||
|
} |
||||||
|
return super.onOptionsItemSelected(item); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
||||||
|
super.onActivityResult(requestCode, resultCode, data); |
||||||
|
|
||||||
|
zxingview.startSpotAndShowRect(); // 显示扫描框,并开始识别
|
||||||
|
|
||||||
|
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_QR_IMAGE) { |
||||||
|
picPath = getPath(this, data.getData()); |
||||||
|
if (StringHelper.isEmpty(picPath)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
scanFromPath(picPath); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void scanFromPath(String path){ |
||||||
|
// 本来就用到 QRCodeView 时可直接调 QRCodeView 的方法,走通用的回调
|
||||||
|
Single.create((SingleOnSubscribe<Bitmap>) emitter -> { |
||||||
|
Bitmap bitmap = BitmapFactory.decodeFile(path); |
||||||
|
if (bitmap == null) |
||||||
|
return; |
||||||
|
if (needScale) { |
||||||
|
int size = 360; |
||||||
|
bitmap = Bitmap.createBitmap(bitmap, bitmap.getWidth() - size, bitmap.getHeight() - size, size, size); |
||||||
|
} |
||||||
|
emitter.onSuccess(bitmap); |
||||||
|
}).compose(RxUtils::toSimpleSingle) |
||||||
|
.subscribe(new MySingleObserver<Bitmap>() { |
||||||
|
@Override |
||||||
|
public void onSuccess(Bitmap bitmap) { |
||||||
|
zxingview.decodeQRCode(bitmap); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void chooseFromGallery() { |
||||||
|
try { |
||||||
|
if (needScale){ |
||||||
|
ToastUtils.showInfo("选择图片仅支持扫描书籍分享图片"); |
||||||
|
} |
||||||
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); |
||||||
|
intent.addCategory(Intent.CATEGORY_OPENABLE); |
||||||
|
intent.setType("image/*"); |
||||||
|
startActivityForResult(intent, REQUEST_QR_IMAGE); |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
ToastUtils.showError(Objects.requireNonNull(e.getLocalizedMessage())); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,271 @@ |
|||||||
|
package xyz.fycz.myreader.ui.activity; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.app.ProgressDialog; |
||||||
|
import android.graphics.Bitmap; |
||||||
|
import android.os.Handler; |
||||||
|
import android.os.Message; |
||||||
|
import android.text.Editable; |
||||||
|
import android.text.TextWatcher; |
||||||
|
import android.text.method.LinkMovementMethod; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.Button; |
||||||
|
import android.widget.CheckBox; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
import androidx.appcompat.widget.Toolbar; |
||||||
|
import butterknife.BindView; |
||||||
|
import com.google.android.material.textfield.TextInputLayout; |
||||||
|
import xyz.fycz.myreader.R; |
||||||
|
import xyz.fycz.myreader.model.backup.UserService; |
||||||
|
import xyz.fycz.myreader.base.BaseActivity; |
||||||
|
import xyz.fycz.myreader.webapi.callback.ResultCallback; |
||||||
|
import xyz.fycz.myreader.ui.dialog.DialogCreator; |
||||||
|
import xyz.fycz.myreader.util.CodeUtil; |
||||||
|
import xyz.fycz.myreader.util.ToastUtils; |
||||||
|
import xyz.fycz.myreader.util.utils.StringUtils; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fengyue |
||||||
|
* @date 2020/9/18 22:37 |
||||||
|
*/ |
||||||
|
public class RegisterActivity extends BaseActivity { |
||||||
|
@BindView(R.id.et_username) |
||||||
|
TextInputLayout etUsername; |
||||||
|
@BindView(R.id.et_password) |
||||||
|
TextInputLayout etPassword; |
||||||
|
@BindView(R.id.et_rp_password) |
||||||
|
TextInputLayout etRpPassword; |
||||||
|
@BindView(R.id.et_captcha) |
||||||
|
TextInputLayout etCaptcha; |
||||||
|
@BindView(R.id.iv_captcha) |
||||||
|
ImageView ivCaptcha; |
||||||
|
@BindView(R.id.bt_register) |
||||||
|
Button btRegister; |
||||||
|
@BindView(R.id.tv_register_tip) |
||||||
|
TextView tvRegisterTip; |
||||||
|
@BindView(R.id.cb_agreement) |
||||||
|
CheckBox cbAgreement; |
||||||
|
@BindView(R.id.tv_agreement) |
||||||
|
TextView tvAgreement; |
||||||
|
private String code; |
||||||
|
private String username = ""; |
||||||
|
private String password = ""; |
||||||
|
private String rpPassword = ""; |
||||||
|
private String inputCode = ""; |
||||||
|
|
||||||
|
@SuppressLint("HandlerLeak") |
||||||
|
private Handler mHandler = new Handler() { |
||||||
|
@SuppressLint("HandlerLeak") |
||||||
|
@Override |
||||||
|
public void handleMessage(Message msg) { |
||||||
|
switch (msg.what) { |
||||||
|
case 1: |
||||||
|
createCaptcha(); |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
showTip((String) msg.obj); |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
tvRegisterTip.setVisibility(View.GONE); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getContentId() { |
||||||
|
return R.layout.activity_register; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void setUpToolbar(Toolbar toolbar) { |
||||||
|
super.setUpToolbar(toolbar); |
||||||
|
setStatusBarColor(R.color.colorPrimary, true); |
||||||
|
getSupportActionBar().setTitle("注册"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initWidget() { |
||||||
|
super.initWidget(); |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(1)); |
||||||
|
etUsername.requestFocus(); |
||||||
|
etUsername.getEditText().addTextChangedListener(new TextWatcher() { |
||||||
|
@Override |
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void afterTextChanged(Editable s) { |
||||||
|
StringUtils.isNotChinese(s); |
||||||
|
username = s.toString(); |
||||||
|
if (username.length() < 6 || username.length() >14){ |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(2, "用户名必须在6-14位之间")); |
||||||
|
} else if(!username.substring(0, 1).matches("^[A-Za-z]$")){ |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(2, |
||||||
|
"用户名只能以字母开头")); |
||||||
|
}else if(!username.matches("^[A-Za-z0-9-_]+$")){ |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(2, |
||||||
|
"用户名只能由数字、字母、下划线、减号组成")); |
||||||
|
}else { |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(3)); |
||||||
|
} |
||||||
|
checkNotNone(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
etPassword.getEditText().addTextChangedListener(new TextWatcher() { |
||||||
|
@Override |
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void afterTextChanged(Editable s) { |
||||||
|
password = s.toString(); |
||||||
|
if (password.length() < 8 || password.length() > 16){ |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(2, "密码必须在8-16位之间")); |
||||||
|
} else if(password.matches("^\\d+$")){ |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(2, "密码不能是纯数字")); |
||||||
|
} else { |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(3)); |
||||||
|
} |
||||||
|
checkNotNone(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
etRpPassword.getEditText().addTextChangedListener(new TextWatcher() { |
||||||
|
@Override |
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void afterTextChanged(Editable s) { |
||||||
|
rpPassword = s.toString(); |
||||||
|
if (!rpPassword.equals(password)){ |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(2, "两次输入的密码不一致")); |
||||||
|
} else { |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(3)); |
||||||
|
} |
||||||
|
checkNotNone(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
etCaptcha.getEditText().addTextChangedListener(new TextWatcher() { |
||||||
|
@Override |
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void afterTextChanged(Editable s) { |
||||||
|
inputCode = s.toString().trim().toLowerCase(); |
||||||
|
if (!inputCode.equals(code.toLowerCase())){ |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(2, "验证码错误")); |
||||||
|
} else { |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(3)); |
||||||
|
} |
||||||
|
checkNotNone(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
tvAgreement.setMovementMethod(LinkMovementMethod.getInstance()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void initClick() { |
||||||
|
super.initClick(); |
||||||
|
ivCaptcha.setOnClickListener(v -> mHandler.sendMessage(mHandler.obtainMessage(1))); |
||||||
|
|
||||||
|
btRegister.setOnClickListener(v -> { |
||||||
|
if (!username.matches("^[A-Za-z][A-Za-z0-9]{5,13}$")){ |
||||||
|
DialogCreator.createTipDialog(this, "用户名格式错误", |
||||||
|
"用户名必须在6-14位之间\n用户名只能以字母开头\n用户名只能由数字、字母、下划线、减号组成"); |
||||||
|
}else if(password.matches("^\\d+$") || !password.matches("^.{8,16}$")){ |
||||||
|
DialogCreator.createTipDialog(this, "密码格式错误", |
||||||
|
"密码必须在8-16位之间\n密码不能是纯数字"); |
||||||
|
}else if(!password.equals(rpPassword)){ |
||||||
|
DialogCreator.createTipDialog(this, "重复密码错误", |
||||||
|
"两次输入的密码不一致"); |
||||||
|
}else if(!inputCode.trim().toLowerCase().equals(code.toLowerCase())){ |
||||||
|
DialogCreator.createTipDialog(this, "验证码错误"); |
||||||
|
}else if(!cbAgreement.isChecked()){ |
||||||
|
DialogCreator.createTipDialog(this, "请勾选同意《用户服务协议》"); |
||||||
|
}else { |
||||||
|
ProgressDialog dialog = DialogCreator.createProgressDialog(this, null, "正在注册..."); |
||||||
|
Map<String, String> userRegisterInfo = new HashMap<>(); |
||||||
|
userRegisterInfo.put("username", username); |
||||||
|
userRegisterInfo.put("password", password); |
||||||
|
UserService.register(userRegisterInfo, new ResultCallback() { |
||||||
|
@Override |
||||||
|
public void onFinish(Object o, int code) { |
||||||
|
String[] info = ((String) o).split(":"); |
||||||
|
int result = Integer.parseInt(info[0].trim()); |
||||||
|
if (result == 101){ |
||||||
|
UserService.writeUsername(username); |
||||||
|
ToastUtils.showSuccess(info[1]); |
||||||
|
finish(); |
||||||
|
}else { |
||||||
|
ToastUtils.showWarring(info[1]); |
||||||
|
} |
||||||
|
dialog.dismiss(); |
||||||
|
} |
||||||
|
@Override |
||||||
|
public void onError(Exception e) { |
||||||
|
ToastUtils.showError("注册失败:\n" + e.getLocalizedMessage()); |
||||||
|
dialog.dismiss(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(1)); |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void createCaptcha() { |
||||||
|
code = CodeUtil.getInstance().createCode(); |
||||||
|
Bitmap codeBitmap = CodeUtil.getInstance().createBitmap(code); |
||||||
|
ivCaptcha.setImageBitmap(codeBitmap); |
||||||
|
} |
||||||
|
|
||||||
|
public void showTip(String tip) { |
||||||
|
tvRegisterTip.setVisibility(View.VISIBLE); |
||||||
|
tvRegisterTip.setText(tip); |
||||||
|
} |
||||||
|
|
||||||
|
public void checkNotNone(){ |
||||||
|
if ("".equals(username) || "".equals(password) || "".equals(rpPassword) || "".equals(inputCode)){ |
||||||
|
btRegister.setEnabled(false); |
||||||
|
}else { |
||||||
|
btRegister.setEnabled(true); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
package xyz.fycz.myreader.ui.popmenu; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.FrameLayout; |
||||||
|
import android.widget.SeekBar; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.annotation.Nullable; |
||||||
|
|
||||||
|
import butterknife.BindView; |
||||||
|
import butterknife.ButterKnife; |
||||||
|
import xyz.fycz.myreader.R; |
||||||
|
import xyz.fycz.myreader.application.SysManager; |
||||||
|
import xyz.fycz.myreader.entity.Setting; |
||||||
|
|
||||||
|
public class AutoPageMenu extends FrameLayout { |
||||||
|
|
||||||
|
@BindView(R.id.tv_auto_scroll_speed) |
||||||
|
TextView tvAutoPageSpeed; |
||||||
|
@BindView(R.id.sb_auto_scroll_progress) |
||||||
|
SeekBar sbAutoPageSpeed; |
||||||
|
@BindView(R.id.tv_exit_auto_page) |
||||||
|
TextView tvExitAutoPage; |
||||||
|
@BindView(R.id.vwNavigationBar) |
||||||
|
View vwNavigationBar; |
||||||
|
|
||||||
|
public AutoPageMenu(@NonNull Context context) { |
||||||
|
super(context); |
||||||
|
init(context); |
||||||
|
} |
||||||
|
|
||||||
|
public AutoPageMenu(@NonNull Context context, @Nullable AttributeSet attrs) { |
||||||
|
super(context, attrs); |
||||||
|
init(context); |
||||||
|
} |
||||||
|
|
||||||
|
public AutoPageMenu(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { |
||||||
|
super(context, attrs, defStyleAttr); |
||||||
|
init(context); |
||||||
|
} |
||||||
|
|
||||||
|
private void init(Context context) { |
||||||
|
View view = LayoutInflater.from(context).inflate(R.layout.menu_auto_page, this); |
||||||
|
ButterKnife.bind(this, view); |
||||||
|
} |
||||||
|
|
||||||
|
public void setListener(Callback callback) { |
||||||
|
Setting setting = SysManager.getSetting(); |
||||||
|
sbAutoPageSpeed.setProgress(110 - setting.getAutoScrollSpeed()); |
||||||
|
tvAutoPageSpeed.setText(String.format("翻页速度:%s %%", 110 - setting.getAutoScrollSpeed())); |
||||||
|
sbAutoPageSpeed.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { |
||||||
|
@Override |
||||||
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { |
||||||
|
tvAutoPageSpeed.setText(String.format("翻页速度:%s %%", progress)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onStartTrackingTouch(SeekBar seekBar) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onStopTrackingTouch(SeekBar seekBar) { |
||||||
|
int progress = seekBar.getProgress(); |
||||||
|
int speed = 110 - progress; |
||||||
|
setting.setAutoScrollSpeed(speed); |
||||||
|
SysManager.saveSetting(setting); |
||||||
|
callback.onSpeedChange(); |
||||||
|
} |
||||||
|
}); |
||||||
|
tvExitAutoPage.setOnClickListener(v -> callback.onExitClick()); |
||||||
|
} |
||||||
|
|
||||||
|
public void setNavigationBarHeight(int height) { |
||||||
|
vwNavigationBar.getLayoutParams().height = height; |
||||||
|
} |
||||||
|
|
||||||
|
public interface Callback{ |
||||||
|
void onSpeedChange(); |
||||||
|
void onExitClick(); |
||||||
|
} |
||||||
|
} |