pull/21/head
fengyuecanzhu 3 years ago
parent f45ad507c4
commit a70c9bb35c
  1. 7
      app/src/main/assets/updatelog.fy
  2. 2
      app/src/main/java/xyz/fycz/myreader/ActivityManage.java
  3. 50
      app/src/main/java/xyz/fycz/myreader/application/App.java
  4. 17
      app/src/main/java/xyz/fycz/myreader/application/CrashHandler.java
  5. 30
      app/src/main/java/xyz/fycz/myreader/base/BaseActivity.java
  6. 2
      app/src/main/java/xyz/fycz/myreader/common/URLCONST.java
  7. 57
      app/src/main/java/xyz/fycz/myreader/entity/AdBean.java
  8. 2
      app/src/main/java/xyz/fycz/myreader/model/user/UserService2.kt
  9. 4
      app/src/main/java/xyz/fycz/myreader/ui/activity/DonateActivity.java
  10. 7
      app/src/main/java/xyz/fycz/myreader/ui/activity/LoginActivity.java
  11. 23
      app/src/main/java/xyz/fycz/myreader/ui/activity/SplashActivity.java
  12. 74
      app/src/main/java/xyz/fycz/myreader/util/SharedPreUtils.java
  13. 41
      app/src/main/java/xyz/fycz/myreader/util/utils/AdUtils.java
  14. 1
      app/src/main/res/layout/activity_donate.xml
  15. 2
      app/src/main/res/layout/activity_login.xml
  16. 2
      app/src/main/res/values/strings.xml

@ -1,3 +1,10 @@
2022.02.17
风月读书v2.3.7
更新内容:
1、新增邮箱登录
2、新增开屏广告
注:由于广告投放次数的需要,此次更新为强制更新
2022.02.07
风月读书v2.3.6
更新内容:

@ -9,6 +9,8 @@ public class ActivityManage {
private static ArrayList<AppCompatActivity> activities = new ArrayList<>();
public static int mResumeActivityCount = 0;
public static void addActivity(AppCompatActivity activity){
activities.add(activity);
}

@ -1,13 +1,15 @@
package xyz.fycz.myreader.application;
import android.annotation.SuppressLint;
import static android.provider.ContactsContract.Directory.PACKAGE_NAME;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@ -34,16 +36,10 @@ import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.File;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import io.reactivex.internal.functions.Functions;
import io.reactivex.plugins.RxJavaPlugins;
import xyz.fycz.myreader.R;
@ -51,18 +47,14 @@ import xyz.fycz.myreader.common.APPCONST;
import xyz.fycz.myreader.common.URLCONST;
import xyz.fycz.myreader.entity.Setting;
import xyz.fycz.myreader.model.sourceAnalyzer.BookSourceManager;
import xyz.fycz.myreader.ui.activity.MainActivity;
import xyz.fycz.myreader.ui.dialog.DialogCreator;
import xyz.fycz.myreader.ui.fragment.BookcaseFragment;
import xyz.fycz.myreader.util.help.SSLSocketClient;
import xyz.fycz.myreader.ui.dialog.UpdateDialog;
import xyz.fycz.myreader.util.SharedPreUtils;
import xyz.fycz.myreader.util.help.StringHelper;
import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.help.SSLSocketClient;
import xyz.fycz.myreader.util.help.StringHelper;
import xyz.fycz.myreader.util.utils.AdUtils;
import xyz.fycz.myreader.util.utils.FileUtils;
import xyz.fycz.myreader.util.utils.NetworkUtils;
import xyz.fycz.myreader.util.utils.OkHttpUtils;
import xyz.fycz.myreader.ui.dialog.UpdateDialog;
public class App extends Application {
@ -72,6 +64,7 @@ public class App extends Application {
private static App application;
private ExecutorService mFixedThreadPool;
private static boolean debug;
public static boolean isBackground = false;
@Override
public void onCreate() {
@ -92,7 +85,6 @@ public class App extends Application {
.readTimeout(15_000) // set read timeout.
))
.commit();
// handleSSLHandshake();
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel();
}
@ -154,31 +146,6 @@ public class App extends Application {
App.getApplication().initNightTheme();
}
@SuppressLint("TrulyRandom")
public static void handleSSLHandshake() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
} catch (Exception ignored) {
}
}
public static Context getmContext() {
return application;
@ -478,4 +445,5 @@ public class App extends Application {
public ExecutorService getmFixedThreadPool() {
return mFixedThreadPool;
}
}

@ -1,10 +1,8 @@
package xyz.fycz.myreader.application;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@ -12,36 +10,21 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;
import androidx.annotation.NonNull;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Function;
import xyz.fycz.myreader.common.APPCONST;
import xyz.fycz.myreader.common.URLCONST;
import xyz.fycz.myreader.ui.activity.CrashActivity;
import xyz.fycz.myreader.ui.activity.RestartActivity;
import xyz.fycz.myreader.ui.activity.SplashActivity;
import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.utils.FileUtils;
import xyz.fycz.myreader.util.utils.OkHttpUtils;
/**
* @author fengyue

@ -5,6 +5,7 @@ import android.content.Intent;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@ -26,7 +27,9 @@ import xyz.fycz.myreader.application.App;
import xyz.fycz.myreader.application.CrashHandler;
import xyz.fycz.myreader.application.SysManager;
import xyz.fycz.myreader.entity.Setting;
import xyz.fycz.myreader.ui.activity.SplashActivity;
import xyz.fycz.myreader.util.StatusBarUtil;
import xyz.fycz.myreader.util.utils.AdUtils;
/**
* @author fengyue
@ -150,6 +153,33 @@ public abstract class BaseActivity extends SwipeBackActivity {
}
}
@Override
protected void onStop() {
super.onStop();
AdUtils.backTime();
ActivityManage.mResumeActivityCount--;
if (ActivityManage.mResumeActivityCount <= 0
&& !App.isBackground){
App.isBackground = true;
Log.d("FYReader", "onActivityStarted: 应用进入后台");
}
}
@Override
protected void onStart() {
super.onStart();
ActivityManage.mResumeActivityCount++;
if (ActivityManage.mResumeActivityCount == 1 &&
App.isBackground) {
App.isBackground = false;
Log.d("FYReader", "onActivityStarted: 应用进入前台");
if (!(this instanceof SplashActivity) && AdUtils.backSplashAd()) {
SplashActivity.start(this);
}
}
}
@Override
protected void onResume() {
super.onResume();

@ -24,10 +24,10 @@ public class URLCONST {
public static final String FY_READER_URL = "https://fyreader." + getDefaultDomain();
public static final String AD_URL = FY_READER_URL + "/ad";
public static final String LOG_UPLOAD_URL = FY_READER_URL + "/logUpload";
public static final String THANKS_URL = FY_READER_URL + "/thanks/";
public static final String USER_URL = "http://101.43.83.105:12123";
public static final String AD_URL = USER_URL + "/do/ad";
public static final String DONATE = "https://gitee.com/fengyuecanzhu/Donate/raw/master";

@ -0,0 +1,57 @@
package xyz.fycz.myreader.entity;
/**
* @author fengyue
* @date 2022/2/17 18:56
*/
public class AdBean {
//是否云控
private boolean isCloud;
//是否有广告
private boolean hasAd;
//应用处于后台一段时间展示开屏广告(单位:分钟)
private int backAdTime;
//应用回到前台展示广告间隔(单位:分钟)
private int intervalAdTime;
public AdBean() {
}
public AdBean(boolean hasAd, int backAdTime, int intervalAdTime) {
this.hasAd = hasAd;
this.backAdTime = backAdTime;
this.intervalAdTime = intervalAdTime;
}
public boolean isCloud() {
return isCloud;
}
public void setCloud(boolean cloud) {
isCloud = cloud;
}
public boolean isHasAd() {
return hasAd;
}
public void setHasAd(boolean hasAd) {
this.hasAd = hasAd;
}
public int getBackAdTime() {
return backAdTime;
}
public void setBackAdTime(int backAdTime) {
this.backAdTime = backAdTime;
}
public int getIntervalAdTime() {
return intervalAdTime;
}
public void setIntervalAdTime(int intervalAdTime) {
this.intervalAdTime = intervalAdTime;
}
}

@ -195,7 +195,7 @@ object UserService2 {
return readConfig() != null
}
private fun makeAuth(): String {
public fun makeAuth(): String {
return "&signal=" + AppInfoUtils.getSingInfo(
App.getmContext(),
App.getApplication().packageName,

@ -62,7 +62,7 @@ public class DonateActivity extends BaseActivity {
private void initAd() {
binding.llAdSupport.setVisibility(View.VISIBLE);
new DdSdkFlowAd().getFlowViews(DonateActivity.this, 4, new DdSdkFlowAd.FlowCallback() {
/*new DdSdkFlowAd().getFlowViews(DonateActivity.this, 4, new DdSdkFlowAd.FlowCallback() {
// 信息流广告拉取完毕后返回的 views
@Override
public void getFlowView(View view) {
@ -81,7 +81,7 @@ public class DonateActivity extends BaseActivity {
public void error(String msg) {
Log.d(TAG, "广告拉取失败\n" + msg);
}
});
});*/
}
@Override

@ -30,6 +30,7 @@ import xyz.fycz.myreader.ui.dialog.LoadingDialog;
import xyz.fycz.myreader.util.CodeUtil;
import xyz.fycz.myreader.util.CyptoUtils;
import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.utils.GsonExtensionsKt;
import xyz.fycz.myreader.util.utils.NetworkUtils;
import xyz.fycz.myreader.util.utils.StringUtils;
@ -112,6 +113,12 @@ public class LoginActivity extends BaseActivity implements TextWatcher {
if (result.getCode() == 102) {
loginSuccess();
ToastUtils.showSuccess(result.getResult().toString());
} else if (result.getCode() == 109) {
user.setUserName(GsonExtensionsKt.getGSON()
.fromJson(result.getResult().toString(), User.class)
.getUserName());
loginSuccess();
ToastUtils.showSuccess("登录成功");
} else if (result.getCode() == 301) {
Intent intent = new Intent(LoginActivity.this, AuthEmailActivity.class);
BitIntentDataManager.getInstance().putData(intent, user);

@ -1,5 +1,7 @@
package xyz.fycz.myreader.ui.activity;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
@ -50,6 +52,9 @@ public class SplashActivity extends BaseActivity {
private int todayAdCount;
private int adTimes;
private boolean hasStart = false;
private boolean startToAd = false;
private static final String INTENT_TO_AD = "startToAd";
//创建子线程
private Runnable start = () -> {
@ -85,6 +90,15 @@ public class SplashActivity extends BaseActivity {
}
};
public static void start(Context context) {
Intent intent = new Intent(context, SplashActivity.class);
if (!(context instanceof Activity)) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
intent.putExtra(INTENT_TO_AD, true);
context.startActivity(intent);
}
@Override
protected void bindView() {
binding = ActivitySplashBinding.inflate(getLayoutInflater());
@ -95,7 +109,7 @@ public class SplashActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 避免从桌面启动程序后,会重新实例化入口类的activity
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0 && !startToAd) {
finish();
return;
}
@ -122,6 +136,7 @@ public class SplashActivity extends BaseActivity {
@Override
protected void initData(Bundle savedInstanceState) {
startToAd = getIntent().getBooleanExtra(INTENT_TO_AD, false);
spu = SharedPreUtils.getInstance();
String splashAdCount = spu.getString("splashAdCount");
adTimes = spu.getInt("curAdTimes", 3);
@ -170,7 +185,6 @@ public class SplashActivity extends BaseActivity {
} else {
startNoAd();
}
}
@Override
@ -193,6 +207,10 @@ public class SplashActivity extends BaseActivity {
private void startNormal() {
if (!App.isDestroy(this)) {
if (startToAd) {
finish();
return;
}
if (BookGroupService.getInstance().curGroupIsPrivate()) {
App.runOnUiThread(() -> {
MyAlertDialog.showPrivateVerifyDia(SplashActivity.this, needGoTo -> {
@ -218,6 +236,7 @@ public class SplashActivity extends BaseActivity {
// 展示成功
@Override
public void show() {
SharedPreUtils.getInstance(true).putLong("splashAdTime", System.currentTimeMillis());
Log.d(TAG, "广告展示成功");
AdUtils.adRecord("splash", "adShow");
countTodayAd();

@ -13,98 +13,110 @@ import java.util.Map;
public class SharedPreUtils {
public static final String SHARED_NAME = "FYReader_pref";
public static final String AD_SHARED_NAME = "FYReader_ad_pref";
private static SharedPreUtils sInstance;
private final SharedPreferences[] sharedReadables;
private SharedPreferences sharedReadable;
private SharedPreferences.Editor sharedWritable;
private SharedPreUtils(){
sharedReadable = App.getmContext()
.getSharedPreferences(SHARED_NAME, Context.MODE_MULTI_PROCESS);
sharedWritable = sharedReadable.edit();
private SharedPreUtils() {
sharedReadables = new SharedPreferences[]{
App.getmContext().getSharedPreferences(SHARED_NAME, Context.MODE_MULTI_PROCESS),
App.getmContext().getSharedPreferences(AD_SHARED_NAME, Context.MODE_MULTI_PROCESS)
};
}
public static SharedPreUtils getInstance(){
if(sInstance == null){
synchronized (SharedPreUtils.class){
if (sInstance == null){
public static SharedPreUtils getInstance() {
return getInstance(false);
}
public static SharedPreUtils getInstance(boolean ad) {
if (sInstance == null) {
synchronized (SharedPreUtils.class) {
if (sInstance == null) {
sInstance = new SharedPreUtils();
}
}
}
sInstance.sharedReadable = sInstance.sharedReadables[!ad ? 0 : 1];
sInstance.sharedWritable = sInstance.sharedReadable.edit();
return sInstance;
}
public SharedPreferences getSharedPreferences(){
public SharedPreferences getSharedPreferences() {
return sharedReadable;
}
public void putString(String key,String value){
sharedWritable.putString(key,value);
public void putString(String key, String value) {
sharedWritable.putString(key, value);
sharedWritable.apply();
}
public void putInt(String key,int value){
public void putInt(String key, int value) {
sharedWritable.putInt(key, value);
sharedWritable.apply();
}
public void putBoolean(String key,boolean value){
public void putBoolean(String key, boolean value) {
sharedWritable.putBoolean(key, value);
sharedWritable.apply();
}
public void putFloat(String key,float value){
public void putFloat(String key, float value) {
sharedWritable.putFloat(key, value);
sharedWritable.apply();
}
public void putLong(String key, long value){
public void putLong(String key, long value) {
sharedWritable.putLong(key, value);
sharedWritable.apply();
}
public String getString(String key){
return getString(key,"");
public String getString(String key) {
return getString(key, "");
}
public String getString(String key, String def){
return sharedReadable.getString(key,def);
public String getString(String key, String def) {
return sharedReadable.getString(key, def);
}
public int getInt(String key){
return getInt(key,0);
public int getInt(String key) {
return getInt(key, 0);
}
public int getInt(String key, int def){
public int getInt(String key, int def) {
return sharedReadable.getInt(key, def);
}
public boolean getBoolean(String key){
return getBoolean(key,false);
public boolean getBoolean(String key) {
return getBoolean(key, false);
}
public boolean getBoolean(String key,boolean def){
public boolean getBoolean(String key, boolean def) {
return sharedReadable.getBoolean(key, def);
}
public float getFloat(String key){
public float getFloat(String key) {
return getFloat(key, 0);
}
public float getFloat(String key, float def){
public float getFloat(String key, float def) {
return sharedReadable.getFloat(key, def);
}
public long getLong(String key){
public long getLong(String key) {
return getLong(key, 0);
}
public long getLong(String key, long def){
public long getLong(String key, long def) {
return sharedReadable.getLong(key, def);
}
public void remove(String key){
public void remove(String key) {
sharedWritable.remove(key).apply();
}
public Map<String, ?> getAll(){
public Map<String, ?> getAll() {
return sharedReadable.getAll();
}

@ -17,7 +17,9 @@ import okhttp3.RequestBody;
import xyz.fycz.myreader.application.App;
import xyz.fycz.myreader.base.observer.MySingleObserver;
import xyz.fycz.myreader.common.URLCONST;
import xyz.fycz.myreader.entity.AdBean;
import xyz.fycz.myreader.model.user.UserService;
import xyz.fycz.myreader.model.user.UserService2;
import xyz.fycz.myreader.util.SharedPreUtils;
import xyz.fycz.myreader.util.help.DateHelper;
@ -28,14 +30,24 @@ import xyz.fycz.myreader.util.help.DateHelper;
public class AdUtils {
public static final String TAG = AdUtils.class.getSimpleName();
private static boolean hasInitAd = false;
public static AdBean adConfig;
static {
String config = SharedPreUtils.getInstance(true).getString("adConfig");
adConfig = GsonExtensionsKt.getGSON().fromJson(config, AdBean.class);
if (adConfig == null || adConfig.getBackAdTime() == 0) {
adConfig = new AdBean(false, 20, 60);
}
}
public static Single<Boolean> checkHasAd() {
return Single.create((SingleOnSubscribe<Boolean>) emitter -> {
boolean hasAd = false;
if (!adConfig.isCloud()) {
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
String body = "type=hasAd" + UserService.makeSignalParam();
String body = "type=adConfig" + UserService2.INSTANCE.makeAuth();
RequestBody requestBody = RequestBody.create(mediaType, body);
String jsonStr = OkHttpUtils.getHtml(URLCONST.AD_URL, requestBody, "UTF-8");
boolean hasAd = false;
try {
JSONObject jsonObject = new JSONObject(jsonStr);
int code = jsonObject.getInt("code");
@ -45,12 +57,18 @@ public class AdUtils {
hasAd = true;
}
} else {
hasAd = jsonObject.getBoolean("result");
String res = jsonObject.getString("result");
SharedPreUtils.getInstance(true).putString("adConfig", res);
adConfig = GsonExtensionsKt.getGSON().fromJson(res, AdBean.class);
hasAd = adConfig.isHasAd();
}
Log.i(TAG, "hasAd:" + hasAd);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
hasAd = adConfig.isHasAd();
}
emitter.onSuccess(hasAd);
}).compose(RxUtils::toSimpleSingle);
}
@ -58,7 +76,7 @@ public class AdUtils {
public static void adRecord(String type, String name) {
Single.create((SingleOnSubscribe<Boolean>) emitter -> {
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
String body = "adType=" + type + "&type=" + name + UserService.makeSignalParam();
String body = "adType=" + type + "&type=" + name + UserService2.INSTANCE.makeAuth();
RequestBody requestBody = RequestBody.create(mediaType, body);
OkHttpUtils.getHtml(URLCONST.AD_URL, requestBody, "UTF-8");
emitter.onSuccess(true);
@ -78,7 +96,7 @@ public class AdUtils {
public static Single<int[]> adTimes() {
return Single.create((SingleOnSubscribe<int[]>) emitter -> {
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
String body = "type=adTimes" + UserService.makeSignalParam();
String body = "type=adTimes" + UserService2.INSTANCE.makeAuth();
RequestBody requestBody = RequestBody.create(mediaType, body);
String jsonStr = OkHttpUtils.getHtml(URLCONST.AD_URL, requestBody, "UTF-8");
JSONObject jsonObject = new JSONObject(jsonStr);
@ -121,6 +139,19 @@ public class AdUtils {
return adTimes < 0 || todayAdCount < adTimes || bookDetailAd;
}
public static void backTime() {
SharedPreUtils.getInstance(true).putLong("backTime", System.currentTimeMillis());
}
public static boolean backSplashAd() {
SharedPreUtils sp = SharedPreUtils.getInstance(true);
Long splashAdTime = sp.getLong("splashAdTime");
Long backTime = sp.getLong("backTime");
Long currentTime = System.currentTimeMillis();
return currentTime - splashAdTime >= adConfig.getIntervalAdTime() * 60L * 1000 ||
currentTime - backTime >= adConfig.getBackAdTime() * 60L * 1000;
}
public static void initAd() {
/*if (!hasInitAd) {
hasInitAd = true;

@ -139,6 +139,7 @@
android:layout_width="match_parent"
android:layout_height="25dp"
android:background="@color/colorForeground"
android:visibility="gone"
android:paddingLeft="5dp"
android:paddingRight="5dp">

@ -34,7 +34,7 @@
android:layout_marginTop="20dp"
android:drawablePadding="10dp"
app:counterEnabled="true"
app:counterMaxLength="14">
app:counterMaxLength="100">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"

@ -95,7 +95,7 @@
<string name="et_email">请输入邮箱</string>
<string name="et_rp_captcha">请输入验证码</string>
<string name="et_email_captcha">请输入邮箱验证码</string>
<string name="et_account_tip">请输入用户名</string>
<string name="et_account_tip">请输入用户名/邮箱</string>
<string name="text_register">注册</string>
<string name="text_agreement_tip">我已阅读并同意《<a href="https://shimo.im/docs/RgkDpd3D3Gp6t3rD">用户服务协议</a></string>

Loading…
Cancel
Save