存储优化

pull/5/head v2.1.0
fengyuecanzhu 4 years ago
parent b76df12486
commit df9054d817
  1. 3
      app/build.gradle
  2. 5
      app/src/main/assets/updatelog.fy
  3. 50
      app/src/main/java/xyz/fycz/myreader/common/APPCONST.java
  4. 2
      app/src/main/java/xyz/fycz/myreader/enums/Font.java
  5. 18
      app/src/main/java/xyz/fycz/myreader/ui/activity/MainActivity.java
  6. 53
      app/src/main/java/xyz/fycz/myreader/ui/activity/QRCodeScanActivity.java
  7. 16
      app/src/main/java/xyz/fycz/myreader/ui/activity/ReplaceRuleActivity.java
  8. 52
      app/src/main/java/xyz/fycz/myreader/ui/activity/SplashActivity.java
  9. 18
      app/src/main/java/xyz/fycz/myreader/ui/adapter/BookcaseAdapter.java
  10. 45
      app/src/main/java/xyz/fycz/myreader/ui/dialog/UpdateDialog.java
  11. 20
      app/src/main/java/xyz/fycz/myreader/ui/fragment/DIYSourceFragment.java
  12. 2
      app/src/main/java/xyz/fycz/myreader/ui/fragment/MineFragment.java
  13. 23
      app/src/main/java/xyz/fycz/myreader/ui/popmenu/CustomizeLayoutMenu.java
  14. 44
      app/src/main/java/xyz/fycz/myreader/ui/presenter/BookcasePresenter.java
  15. 31
      app/src/main/java/xyz/fycz/myreader/util/PermissionsChecker.java
  16. 1
      app/src/main/java/xyz/fycz/myreader/util/help/JsExtensions.java
  17. 4
      app/src/main/java/xyz/fycz/myreader/util/utils/FileUtils.java
  18. 5
      app/src/main/res/values/strings.xml
  19. 4
      app/version_code.properties

@ -210,6 +210,9 @@ dependencies {
//noinspection GradleDependency //noinspection GradleDependency
implementation 'com.github.gedoor:rhino-android:1.3' implementation 'com.github.gedoor:rhino-android:1.3'
//XXPermissions
implementation 'com.github.getActivity:XXPermissions:11.2'
} }
greendao { greendao {

@ -1,3 +1,8 @@
2021.06.06
风月读书v2.1.0
更新内容:
1、储存优化
2021.06.05 2021.06.05
风月读书v2.0.9 风月读书v2.0.9
更新内容: 更新内容:

@ -3,8 +3,11 @@ package xyz.fycz.myreader.common;
import android.os.Environment; import android.os.Environment;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import xyz.fycz.myreader.R; import xyz.fycz.myreader.R;
import xyz.fycz.myreader.application.App;
import xyz.fycz.myreader.util.utils.FileUtils; import xyz.fycz.myreader.util.utils.FileUtils;
import java.io.File; import java.io.File;
@ -22,21 +25,34 @@ public class APPCONST {
public static String privateKey;//app私钥 public static String privateKey;//app私钥
public static final String KEY = ""; public static final String KEY = "";
public static final String[] STORAGE_PERMISSIONS = new String[]{Permission.WRITE_EXTERNAL_STORAGE,
Permission.READ_EXTERNAL_STORAGE};
public static final String FILE_DIR = Environment.getExternalStorageDirectory() + "/FYReader/"; public static final String FILE_DIR = Environment.getExternalStorageDirectory() + "/FYReader/";
public static final String SHARE_FILE_DIR = Environment.getExternalStorageDirectory() + "/FYReader/share/"; public static String TXT_BOOK_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/FYReader/noveltxt/";
public static final String LOG_DIR = Environment.getExternalStorageDirectory() + "/FYReader/log/";
public static final String BG_FILE_DIR = Environment.getExternalStorageDirectory() + "/FYReader/bg/"; public static String SHARE_FILE_DIR = (hasStoragePermission() ?
public static final String TEM_FILE_DIR = Environment.getExternalStorageDirectory() + "/FYReader/tem/"; Environment.getExternalStorageDirectory().getAbsolutePath() :
public static final String BACKUP_FILE_DIR = Environment.getExternalStorageDirectory() + "/FYReader/backup/"; FileUtils.getDataDir()) + "/FYReader/share/";
public static final String TXT_BOOK_DIR = Environment.getExternalStorageDirectory() + "/FYReader/noveltxt/"; public static String LOG_DIR = (hasStoragePermission() ?
public static final String FONT_BOOK_DIR = Environment.getExternalStorageDirectory() + "/FYReader/font/"; Environment.getExternalStorageDirectory().getAbsolutePath() :
public static final String UPDATE_APK_FILE_DIR = Environment.getExternalStorageDirectory() + "/FYReader/apk/"; FileUtils.getDataDir()) + "/FYReader/log/";
public static final String QQ_DATA_DIR = Environment.getExternalStorageDirectory() + "/tencent/MobileQQ/data/"; public static String BG_FILE_DIR = (hasStoragePermission() ?
Environment.getExternalStorageDirectory().getAbsolutePath() :
FileUtils.getDataDir()) + "/FYReader/bg/";
public static String TEM_FILE_DIR = (hasStoragePermission() ?
Environment.getExternalStorageDirectory().getAbsolutePath() :
FileUtils.getDataDir()) + "/FYReader/tem/";
public static String BACKUP_FILE_DIR = (hasStoragePermission() ?
Environment.getExternalStorageDirectory().getAbsolutePath() :
FileUtils.getDataDir()) + "/FYReader/backup/";
public static String FONT_BOOK_DIR = (hasStoragePermission() ?
Environment.getExternalStorageDirectory().getAbsolutePath() :
FileUtils.getDataDir()) + "/FYReader/font/";
public static String QQ_DATA_DIR = Environment.getExternalStorageDirectory() + "/tencent/MobileQQ/data/";
//BookCachePath (因为getCachePath引用了Context,所以必须是静态变量,不能够是静态常量) //BookCachePath (因为getCachePath引用了Context,所以必须是静态变量,不能够是静态常量)
public static String BOOK_CACHE_PATH = FileUtils.getCachePath() + File.separator public static String BOOK_CACHE_PATH = FileUtils.getCachePath() + File.separator
+ "book_cache"+ File.separator ; + "book_cache" + File.separator;
public static String HTML_CACHE_PATH = FileUtils.getCachePath() + File.separator
+ "html_cache"+ File.separator ;
public static long exitTime; public static long exitTime;
public static final int exitConfirmTime = 2000; public static final int exitConfirmTime = 2000;
@ -94,8 +110,6 @@ public class APPCONST {
public static final int SELECT_FILE_CODE = 10000; public static final int SELECT_FILE_CODE = 10000;
public static final int PERMISSIONS_REQUEST_STORAGE = 10001;
//设置版本号 //设置版本号
public static final int SETTING_VERSION = 11; public static final int SETTING_VERSION = 11;
@ -120,4 +134,12 @@ public class APPCONST {
public static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4168.3 Safari/537.36"; public static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4168.3 Safari/537.36";
private static Boolean hasStoragePermission = null;
public static boolean hasStoragePermission() {
if (hasStoragePermission == null) {
hasStoragePermission = XXPermissions.isGranted(App.getmContext(), STORAGE_PERMISSIONS);
}
return hasStoragePermission;
}
} }

@ -6,7 +6,7 @@ public enum Font {
默认字体( "默认字体"), 默认字体( "默认字体"),
本地字体( "默认字体"), 本地字体( "默认字体"),
方正楷体( URLCONST.LAN_ZOUS_URL + " /ilLFMe6kefe"), 方正楷体( URLCONST.LAN_ZOUS_URL + "/ilLFMe6kefe"),
方正行楷( URLCONST.LAN_ZOUS_URL + "/imFvne6keji"), 方正行楷( URLCONST.LAN_ZOUS_URL + "/imFvne6keji"),
经典宋体(URLCONST.LAN_ZOUS_URL + "/idhI5e6keqf"), 经典宋体(URLCONST.LAN_ZOUS_URL + "/idhI5e6keqf"),
方正硬笔行书(URLCONST.LAN_ZOUS_URL + "/ilVh6ep9xja"), 方正硬笔行书(URLCONST.LAN_ZOUS_URL + "/ilVh6ep9xja"),

@ -386,24 +386,6 @@ public class MainActivity extends BaseActivity {
} }
} }
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case APPCONST.PERMISSIONS_REQUEST_STORAGE: {
// 如果取消权限,则返回的值为0
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//跳转到 FileSystemActivity
Intent intent = new Intent(this, FileSystemActivity.class);
startActivity(intent);
} else {
ToastUtils.showWarring("用户拒绝开启读写权限");
}
}
}
}
@Override @Override
protected void onDestroy() { protected void onDestroy() {

@ -2,7 +2,6 @@ package xyz.fycz.myreader.ui.activity;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.os.Bundle; import android.os.Bundle;
@ -11,9 +10,13 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import java.util.List;
import cn.bingoogolapple.qrcode.core.QRCodeView; import cn.bingoogolapple.qrcode.core.QRCodeView;
import io.reactivex.Single; import io.reactivex.Single;
@ -22,7 +25,6 @@ import xyz.fycz.myreader.R;
import xyz.fycz.myreader.base.BaseActivity; import xyz.fycz.myreader.base.BaseActivity;
import xyz.fycz.myreader.base.observer.MySingleObserver; import xyz.fycz.myreader.base.observer.MySingleObserver;
import xyz.fycz.myreader.databinding.ActivityQrcodeCaptureBinding; import xyz.fycz.myreader.databinding.ActivityQrcodeCaptureBinding;
import xyz.fycz.myreader.util.PermissionsChecker;
import xyz.fycz.myreader.util.help.StringHelper; import xyz.fycz.myreader.util.help.StringHelper;
import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.utils.RxUtils; import xyz.fycz.myreader.util.utils.RxUtils;
@ -40,8 +42,6 @@ public class QRCodeScanActivity extends BaseActivity implements QRCodeView.Deleg
private ActivityQrcodeCaptureBinding binding; private ActivityQrcodeCaptureBinding binding;
private final int REQUEST_QR_IMAGE = 202; 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 flashlightIsOpen;
private boolean needScale = true; private boolean needScale = true;
private String picPath; private String picPath;
@ -104,16 +104,16 @@ public class QRCodeScanActivity extends BaseActivity implements QRCodeView.Deleg
public void onScanQRCodeSuccess(String result) { public void onScanQRCodeSuccess(String result) {
Log.d("onScanQRCodeSuccess", needScale + ""); Log.d("onScanQRCodeSuccess", needScale + "");
if (result == null) { if (result == null) {
if (!needScale){ if (!needScale) {
needScale = true; needScale = true;
if (StringHelper.isEmpty(picPath)) { if (StringHelper.isEmpty(picPath)) {
return; return;
} }
scanFromPath(picPath); scanFromPath(picPath);
}else { } else {
ToastUtils.showError("二维码扫描失败"); ToastUtils.showError("二维码扫描失败");
} }
}else { } else {
Intent intent = new Intent(); Intent intent = new Intent();
Log.d("result", result); Log.d("result", result);
intent.putExtra("result", result); intent.putExtra("result", result);
@ -124,9 +124,9 @@ public class QRCodeScanActivity extends BaseActivity implements QRCodeView.Deleg
@Override @Override
public void onCameraAmbientBrightnessChanged(boolean isDark) { public void onCameraAmbientBrightnessChanged(boolean isDark) {
if (isDark){ if (isDark) {
binding.llFlashlight.setVisibility(View.VISIBLE); binding.llFlashlight.setVisibility(View.VISIBLE);
}else { } else {
if (!flashlightIsOpen) { if (!flashlightIsOpen) {
binding.llFlashlight.setVisibility(View.GONE); binding.llFlashlight.setVisibility(View.GONE);
} }
@ -144,32 +144,23 @@ public class QRCodeScanActivity extends BaseActivity implements QRCodeView.Deleg
} }
private void requestPermission() { private void requestPermission() {
//获取读取和写入SD卡的权限 //获取相机权限
if (new PermissionsChecker(this).lacksPermissions(CAMERA)) { XXPermissions.with(this)
ActivityCompat.requestPermissions(this, new String[]{CAMERA}, PERMISSIONS_REQUEST_CAMERA); .permission(Permission.CAMERA)
} else { .request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
//申请权限成功
startScan(); startScan();
} }
}
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onDenied(List<String> permissions, boolean never) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSIONS_REQUEST_CAMERA: {
// 如果取消权限,则返回的值为0
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//申请权限成功
startScan();
} else {
//申请权限失败 //申请权限失败
finish(); finish();
ToastUtils.showWarring("请给予相机权限,否则无法进行扫码!"); ToastUtils.showWarring("请给予相机权限,否则无法进行扫码!");
} }
return; });
}
}
} }
// 添加菜单 // 添加菜单
@ -206,7 +197,7 @@ public class QRCodeScanActivity extends BaseActivity implements QRCodeView.Deleg
} }
} }
private void scanFromPath(String path){ private void scanFromPath(String path) {
// 本来就用到 QRCodeView 时可直接调 QRCodeView 的方法,走通用的回调 // 本来就用到 QRCodeView 时可直接调 QRCodeView 的方法,走通用的回调
Single.create((SingleOnSubscribe<Bitmap>) emitter -> { Single.create((SingleOnSubscribe<Bitmap>) emitter -> {
Bitmap bitmap = BitmapFactory.decodeFile(path); Bitmap bitmap = BitmapFactory.decodeFile(path);
@ -228,7 +219,7 @@ public class QRCodeScanActivity extends BaseActivity implements QRCodeView.Deleg
private void chooseFromGallery() { private void chooseFromGallery() {
try { try {
if (needScale){ if (needScale) {
ToastUtils.showInfo("选择图片仅支持扫描书籍分享图片"); ToastUtils.showInfo("选择图片仅支持扫描书籍分享图片");
} }
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); Intent intent = new Intent(Intent.ACTION_GET_CONTENT);

@ -17,6 +17,8 @@ import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.XXPermissions;
import com.kongzue.dialogx.dialogs.BottomMenu; import com.kongzue.dialogx.dialogs.BottomMenu;
import java.util.ArrayList; import java.util.ArrayList;
@ -244,11 +246,23 @@ public class ReplaceRuleActivity extends BaseActivity {
ToastUtils.showWarring("当前没有任何规则,无法导出!"); ToastUtils.showWarring("当前没有任何规则,无法导出!");
return true; return true;
} }
XXPermissions.with(this)
.permission(APPCONST.STORAGE_PERMISSIONS)
.request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
if (FileUtils.writeText(GsonExtensionsKt.getGSON().toJson(mReplaceRules), if (FileUtils.writeText(GsonExtensionsKt.getGSON().toJson(mReplaceRules),
FileUtils.getFile(APPCONST.FILE_DIR + "ReplaceRule.json"))) { FileUtils.getFile(APPCONST.FILE_DIR + "ReplaceRule.json"))) {
DialogCreator.createTipDialog(this, DialogCreator.createTipDialog(ReplaceRuleActivity.this,
"内容替换规则导出成功,导出位置:" + APPCONST.FILE_DIR + "ReplaceRule.json"); "内容替换规则导出成功,导出位置:" + APPCONST.FILE_DIR + "ReplaceRule.json");
} }
}
@Override
public void onDenied(List<String> permissions, boolean never) {
ToastUtils.showWarring("没有储存权限!");
}
});
} else if (itemId == R.id.action_reverse) { } else if (itemId == R.id.action_reverse) {
for (ReplaceRuleBean ruleBean : mReplaceRules) { for (ReplaceRuleBean ruleBean : mReplaceRules) {
ruleBean.setEnable(!ruleBean.getEnable()); ruleBean.setEnable(!ruleBean.getEnable());

@ -17,11 +17,15 @@ import androidx.core.app.ActivityCompat;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.signature.ObjectKey; import com.bumptech.glide.signature.ObjectKey;
import com.gyf.immersionbar.ImmersionBar; import com.gyf.immersionbar.ImmersionBar;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.weaction.ddsdk.ad.DdSdkSplashAd; import com.weaction.ddsdk.ad.DdSdkSplashAd;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.List;
import xyz.fycz.myreader.R; import xyz.fycz.myreader.R;
import xyz.fycz.myreader.application.App; import xyz.fycz.myreader.application.App;
@ -33,7 +37,6 @@ import xyz.fycz.myreader.greendao.service.BookGroupService;
import xyz.fycz.myreader.ui.dialog.MyAlertDialog; import xyz.fycz.myreader.ui.dialog.MyAlertDialog;
import xyz.fycz.myreader.util.help.DateHelper; import xyz.fycz.myreader.util.help.DateHelper;
import xyz.fycz.myreader.util.IOUtils; import xyz.fycz.myreader.util.IOUtils;
import xyz.fycz.myreader.util.PermissionsChecker;
import xyz.fycz.myreader.util.SharedPreUtils; import xyz.fycz.myreader.util.SharedPreUtils;
import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.utils.AdUtils; import xyz.fycz.myreader.util.utils.AdUtils;
@ -46,12 +49,6 @@ public class SplashActivity extends BaseActivity {
/*************Constant**********/ /*************Constant**********/
public static final String TAG = SplashActivity.class.getSimpleName(); public static final String TAG = SplashActivity.class.getSimpleName();
public static int WAIT_INTERVAL = 0; public static int WAIT_INTERVAL = 0;
private static final int PERMISSIONS_REQUEST_STORAGE = 1;
static final String[] PERMISSIONS = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private ActivitySplashBinding binding; private ActivitySplashBinding binding;
private SharedPreUtils spu; private SharedPreUtils spu;
@ -59,7 +56,6 @@ public class SplashActivity extends BaseActivity {
private int adTimes; private int adTimes;
private boolean hasStart = false; private boolean hasStart = false;
private PermissionsChecker mPermissionsChecker;
//创建子线程 //创建子线程
private Runnable start = () -> { private Runnable start = () -> {
if (!hasStart && !App.isDestroy(SplashActivity.this)) { if (!hasStart && !App.isDestroy(SplashActivity.this)) {
@ -115,22 +111,12 @@ public class SplashActivity extends BaseActivity {
//loadImage(); //loadImage();
boolean agreePrivacyPolicy = SharedPreUtils.getInstance().getBoolean("agreePrivacyPolicy"); boolean agreePrivacyPolicy = SharedPreUtils.getInstance().getBoolean("agreePrivacyPolicy");
if (agreePrivacyPolicy) { if (agreePrivacyPolicy) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
mPermissionsChecker = new PermissionsChecker(this);
requestPermission(); requestPermission();
} else {
start();
}
} else { } else {
MyAlertDialog.showPrivacyDialog(this, (dialog, which) -> { MyAlertDialog.showPrivacyDialog(this, (dialog, which) -> {
SharedPreUtils.getInstance().putBoolean("agreePrivacyPolicy", true); SharedPreUtils.getInstance().putBoolean("agreePrivacyPolicy", true);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
mPermissionsChecker = new PermissionsChecker(this);
requestPermission(); requestPermission();
} else { }, (dialog, which) -> android.os.Process.killProcess(android.os.Process.myPid()));
start();
}
}, (dialog, which) -> finish());
} }
} }
@ -348,33 +334,23 @@ public class SplashActivity extends BaseActivity {
private void requestPermission() { private void requestPermission() {
//获取读取和写入SD卡的权限 //获取读取和写入SD卡的权限
if (mPermissionsChecker.lacksPermissions(PERMISSIONS)) { XXPermissions.with(this)
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSIONS_REQUEST_STORAGE); .permission(APPCONST.STORAGE_PERMISSIONS)
} else { .request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
start(); start();
} }
}
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onDenied(List<String> permissions, boolean never) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults); ToastUtils.showWarring("储存权限被拒绝,部分功能可能无法正常运行!");
switch (requestCode) {
case PERMISSIONS_REQUEST_STORAGE: {
// 如果取消权限,则返回的值为0
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//申请权限成功
start(); start();
} else {
//申请权限失败
finish();
ToastUtils.showWarring("请给予储存权限,否则程序无法正常运行!");
}
return;
}
} }
});
} }
private void countTodayAd() { private void countTodayAd() {
String today = DateHelper.getYearMonthDay1(); String today = DateHelper.getYearMonthDay1();
todayAdCount++; todayAdCount++;

@ -12,6 +12,8 @@ import androidx.annotation.NonNull;
import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.SwitchCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.XXPermissions;
import com.kongzue.dialogx.dialogs.BottomDialog; import com.kongzue.dialogx.dialogs.BottomDialog;
import com.kongzue.dialogx.dialogs.BottomMenu; import com.kongzue.dialogx.dialogs.BottomMenu;
import com.kongzue.dialogx.interfaces.OnBindView; import com.kongzue.dialogx.interfaces.OnBindView;
@ -450,7 +452,23 @@ public abstract class BookcaseAdapter extends RecyclerView.Adapter<BookcaseAdapt
tvExport.setOnClickListener(v -> { tvExport.setOnClickListener(v -> {
dialog.dismiss(); dialog.dismiss();
Single.create((SingleOnSubscribe<Boolean>) emitter -> { Single.create((SingleOnSubscribe<Boolean>) emitter -> {
XXPermissions.with(mContext)
.permission(APPCONST.STORAGE_PERMISSIONS)
.request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
try {
emitter.onSuccess(unionChapterCathe(mBook)); emitter.onSuccess(unionChapterCathe(mBook));
} catch (IOException e) {
emitter.onError(e);
}
}
@Override
public void onDenied(List<String> permissions, boolean never) {
ToastUtils.showWarring("没有储存权限!");
}
});
}).compose(RxUtils::toSimpleSingle).subscribe(new MySingleObserver<Boolean>() { }).compose(RxUtils::toSimpleSingle).subscribe(new MySingleObserver<Boolean>() {
@Override @Override
public void onSuccess(@NotNull Boolean aBoolean) { public void onSuccess(@NotNull Boolean aBoolean) {

@ -25,6 +25,9 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.FragmentTransaction;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.liulishuo.filedownloader.BaseDownloadTask; import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadLargeFileListener; import com.liulishuo.filedownloader.FileDownloadLargeFileListener;
import com.liulishuo.filedownloader.FileDownloader; import com.liulishuo.filedownloader.FileDownloader;
@ -35,9 +38,11 @@ import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.List;
import xyz.fycz.myreader.R; import xyz.fycz.myreader.R;
import xyz.fycz.myreader.application.App; import xyz.fycz.myreader.application.App;
import xyz.fycz.myreader.common.APPCONST;
import xyz.fycz.myreader.databinding.FragmentUpdateBinding; import xyz.fycz.myreader.databinding.FragmentUpdateBinding;
import xyz.fycz.myreader.util.ToastUtils; import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.webapi.LanZousApi; import xyz.fycz.myreader.webapi.LanZousApi;
@ -91,11 +96,19 @@ public class UpdateDialog extends Fragment {
// if (listener != null) { // if (listener != null) {
// listener.onConfirm(v); // listener.onConfirm(v);
// } else { // } else {
if (ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { XXPermissions.with(mActivity)
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_WRITE_EXTERNAL_STORAGE); .permission(APPCONST.STORAGE_PERMISSIONS)
} else { .request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
downloadApk(appUrl); downloadApk(appUrl);
} }
@Override
public void onDenied(List<String> permissions, boolean never) {
ToastUtils.showWarring("请勿拒绝储存权限,否则无法更新应用!");
}
});
// } // }
}); });
binding.btBrowser.setOnClickListener(v -> { binding.btBrowser.setOnClickListener(v -> {
@ -255,7 +268,7 @@ public class UpdateDialog extends Fragment {
baseDownloadTask = FileDownloader.getImpl() baseDownloadTask = FileDownloader.getImpl()
.create(decodeUrl) .create(decodeUrl)
.setPath(path, new File(path).isDirectory()) .setPath(path, new File(path).isDirectory())
.setCallbackProgressMinInterval(100) .setCallbackProgressMinInterval(30)
.setListener(new FileDownloadLargeFileListener() { .setListener(new FileDownloadLargeFileListener() {
@Override @Override
protected void pending(BaseDownloadTask task, long soFarBytes, long totalBytes) { protected void pending(BaseDownloadTask task, long soFarBytes, long totalBytes) {
@ -300,30 +313,6 @@ public class UpdateDialog extends Fragment {
baseDownloadTask.start(); baseDownloadTask.start();
} }
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_WRITE_EXTERNAL_STORAGE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 权限被用户同意,可以去放肆了。
if (ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
} else {
downloadApk(appUrl);
}
} else {
// 权限被用户拒绝了,洗洗睡吧。
}
}
}
/** /**
* 安装 * 安装

@ -17,6 +17,8 @@ import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.XXPermissions;
import com.kongzue.dialogx.dialogs.BottomMenu; import com.kongzue.dialogx.dialogs.BottomMenu;
import java.io.File; import java.io.File;
@ -197,7 +199,7 @@ public class DIYSourceFragment extends BaseFragment {
}); });
binding.tvSourceTip.setOnClickListener(v -> { binding.tvSourceTip.setOnClickListener(v -> {
MyAlertDialog.showTipDialogWithLink(getContext(), "书源说明",R.string.DIY_source_tip); MyAlertDialog.showTipDialogWithLink(getContext(), "书源说明", R.string.DIY_source_tip);
}); });
binding.ivGroup.setOnClickListener(this::showSourceGroupMenu); binding.ivGroup.setOnClickListener(this::showSourceGroupMenu);
@ -383,6 +385,11 @@ public class DIYSourceFragment extends BaseFragment {
ToastUtils.showWarring("当前没有选择任何书源,无法导出!"); ToastUtils.showWarring("当前没有选择任何书源,无法导出!");
return; return;
} }
XXPermissions.with(this)
.permission(APPCONST.STORAGE_PERMISSIONS)
.request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
Single.create((SingleOnSubscribe<Boolean>) emitter -> { Single.create((SingleOnSubscribe<Boolean>) emitter -> {
emitter.onSuccess(FileUtils.writeText(GsonExtensionsKt.getGSON().toJson(sources), emitter.onSuccess(FileUtils.writeText(GsonExtensionsKt.getGSON().toJson(sources),
FileUtils.getFile(APPCONST.FILE_DIR + "BookSources.json"))); FileUtils.getFile(APPCONST.FILE_DIR + "BookSources.json")));
@ -399,6 +406,13 @@ public class DIYSourceFragment extends BaseFragment {
}); });
} }
@Override
public void onDenied(List<String> permissions, boolean never) {
ToastUtils.showWarring("没有储存权限!");
}
});
}
private void shareSources(List<BookSource> bookSources) { private void shareSources(List<BookSource> bookSources) {
if (bookSources == null || bookSources.size() == 0) { if (bookSources == null || bookSources.size() == 0) {
ToastUtils.showWarring("当前没有选择任何书源,无法分享!"); ToastUtils.showWarring("当前没有选择任何书源,无法分享!");
@ -406,9 +420,9 @@ public class DIYSourceFragment extends BaseFragment {
} }
Single.create((SingleOnSubscribe<File>) emitter -> { Single.create((SingleOnSubscribe<File>) emitter -> {
File share = FileUtils.getFile(APPCONST.SHARE_FILE_DIR + "ShareBookSources.json"); File share = FileUtils.getFile(APPCONST.SHARE_FILE_DIR + "ShareBookSources.json");
if (FileUtils.writeText(GsonExtensionsKt.getGSON().toJson(bookSources), share)){ if (FileUtils.writeText(GsonExtensionsKt.getGSON().toJson(bookSources), share)) {
emitter.onSuccess(share); emitter.onSuccess(share);
}else { } else {
emitter.onError(new Exception("书源文件写出失败")); emitter.onError(new Exception("书源文件写出失败"));
} }
}).compose(RxUtils::toSimpleSingle).subscribe(new MySingleObserver<File>() { }).compose(RxUtils::toSimpleSingle).subscribe(new MySingleObserver<File>() {

@ -390,7 +390,7 @@ public class MineFragment extends BaseFragment {
@Override @Override
public void backupError(@io.reactivex.annotations.NonNull String msg) { public void backupError(@io.reactivex.annotations.NonNull String msg) {
DialogCreator.createTipDialog(getContext(), "未给予储存权限,备份失败!"); DialogCreator.createTipDialog(getContext(), "未给予储存权限,备份失败!\n" + msg);
} }
}, false); }, false);
}, (dialogInterface, i) -> dialogInterface.dismiss()); }, (dialogInterface, i) -> dialogInterface.dismiss());

@ -22,6 +22,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.XXPermissions;
import com.jaredrummler.android.colorpicker.ColorPickerDialog; import com.jaredrummler.android.colorpicker.ColorPickerDialog;
import com.kongzue.dialogx.dialogs.BottomMenu; import com.kongzue.dialogx.dialogs.BottomMenu;
@ -95,7 +97,7 @@ public class CustomizeLayoutMenu extends FrameLayout {
public void upColor() { public void upColor() {
int curStyleIndex = setting.getCurReadStyleIndex(); int curStyleIndex = setting.getCurReadStyleIndex();
if (!setting.isDayStyle()){ if (!setting.isDayStyle()) {
ToastUtils.showInfo("当前正在编辑夜间模式"); ToastUtils.showInfo("当前正在编辑夜间模式");
curStyleIndex = 6; curStyleIndex = 6;
} }
@ -237,10 +239,22 @@ public class CustomizeLayoutMenu extends FrameLayout {
}).show();*/ }).show();*/
BottomMenu.show("选择需要导出的布局", items) BottomMenu.show("选择需要导出的布局", items)
.setOnMenuItemClickListener((dialog, text, which) -> { .setOnMenuItemClickListener((dialog, text, which) -> {
if (setting.exportLayout(which)){ XXPermissions.with(context)
.permission(APPCONST.STORAGE_PERMISSIONS)
.request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
if (setting.exportLayout(which)) {
DialogCreator.createTipDialog(context, DialogCreator.createTipDialog(context,
"布局配置导出成功,导出位置:" + APPCONST.FILE_DIR + "readConfig.zip"); "布局配置导出成功,导出位置:" + APPCONST.FILE_DIR + "readConfig.zip");
} }
}
@Override
public void onDenied(List<String> permissions, boolean never) {
ToastUtils.showWarring("没有储存权限!");
}
});
return false; return false;
}); });
} }
@ -274,8 +288,8 @@ public class CustomizeLayoutMenu extends FrameLayout {
BottomMenu.show("选择要覆盖的布局", items) BottomMenu.show("选择要覆盖的布局", items)
.setOnMenuItemClickListener((dialog, text, which) -> { .setOnMenuItemClickListener((dialog, text, which) -> {
setting.importLayout(which, readStyle); setting.importLayout(which, readStyle);
if (!readStyle.bgIsColor() && !readStyle.bgIsAssert()){ if (!readStyle.bgIsColor() && !readStyle.bgIsAssert()) {
FileUtils.copy(APPCONST.TEM_FILE_DIR + "bg.fyl",APPCONST.BG_FILE_DIR + "bg" + which + ".fyl"); FileUtils.copy(APPCONST.TEM_FILE_DIR + "bg.fyl", APPCONST.BG_FILE_DIR + "bg" + which + ".fyl");
readStyle.setBgPath(APPCONST.BG_FILE_DIR + "bg" + which + ".fyl"); readStyle.setBgPath(APPCONST.BG_FILE_DIR + "bg" + which + ".fyl");
} }
FileUtils.deleteFile(APPCONST.TEM_FILE_DIR + "readConfig.fyl"); FileUtils.deleteFile(APPCONST.TEM_FILE_DIR + "readConfig.fyl");
@ -292,6 +306,7 @@ public class CustomizeLayoutMenu extends FrameLayout {
public interface Callback { public interface Callback {
void upBg(); void upBg();
void upStyle(); void upStyle();
} }

@ -21,6 +21,9 @@ import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.kongzue.dialogx.dialogs.BottomMenu; import com.kongzue.dialogx.dialogs.BottomMenu;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -85,7 +88,6 @@ public class BookcasePresenter implements BasePresenter {
private final ChapterService mChapterService; private final ChapterService mChapterService;
private final BookGroupService mBookGroupService; private final BookGroupService mBookGroupService;
private final MainActivity mMainActivity; private final MainActivity mMainActivity;
private PermissionsChecker mPermissionsChecker;
private boolean isBookcaseStyleChange; private boolean isBookcaseStyleChange;
private Setting mSetting; private Setting mSetting;
private final List<Book> errorLoadingBooks = new ArrayList<>(); private final List<Book> errorLoadingBooks = new ArrayList<>();
@ -356,7 +358,7 @@ public class BookcasePresenter implements BasePresenter {
} }
public void refreshBook(Book book, boolean isChangeSource){ public void refreshBook(Book book, boolean isChangeSource) {
mBookcaseAdapter.getIsLoading().put(book.getId(), true); mBookcaseAdapter.getIsLoading().put(book.getId(), true);
mBookcaseAdapter.refreshBook(book.getChapterUrl()); mBookcaseAdapter.refreshBook(book.getChapterUrl());
final ArrayList<Chapter> mChapters = (ArrayList<Chapter>) mChapterService.findBookAllChapterByBookId(book.getId()); final ArrayList<Chapter> mChapters = (ArrayList<Chapter>) mChapterService.findBookAllChapterByBookId(book.getId());
@ -367,7 +369,7 @@ public class BookcasePresenter implements BasePresenter {
book.setNewestChapterTitle(chapters.get(chapters.size() - 1).getTitle()); book.setNewestChapterTitle(chapters.get(chapters.size() - 1).getTitle());
mChapterService.updateAllOldChapterData(mChapters, chapters, book.getId()); mChapterService.updateAllOldChapterData(mChapters, chapters, book.getId());
mBookService.updateEntity(book); mBookService.updateEntity(book);
if (isChangeSource){ if (isChangeSource) {
if (mBookService.matchHistoryChapterPos(book, chapters)) { if (mBookService.matchHistoryChapterPos(book, chapters)) {
ToastUtils.showSuccess("历史阅读章节匹配成功!"); ToastUtils.showSuccess("历史阅读章节匹配成功!");
} else { } else {
@ -487,19 +489,7 @@ public class BookcasePresenter implements BasePresenter {
showGroupManDia(); showGroupManDia();
return true; return true;
case R.id.action_addLocalBook: case R.id.action_addLocalBook:
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { addLocalBook();
if (mPermissionsChecker == null) {
mPermissionsChecker = new PermissionsChecker(mMainActivity);
}
//获取读取和写入SD卡的权限
if (mPermissionsChecker.lacksPermissions(PERMISSIONS)) {
//请求权限
ActivityCompat.requestPermissions(mMainActivity, PERMISSIONS, APPCONST.PERMISSIONS_REQUEST_STORAGE);
return true;
}
}
Intent fileSystemIntent = new Intent(mMainActivity, FileSystemActivity.class);
mMainActivity.startActivity(fileSystemIntent);
break; break;
case R.id.action_download_all: case R.id.action_download_all:
if (!SharedPreUtils.getInstance().getBoolean(mMainActivity.getString(R.string.isReadDownloadAllTip), false)) { if (!SharedPreUtils.getInstance().getBoolean(mMainActivity.getString(R.string.isReadDownloadAllTip), false)) {
@ -518,6 +508,23 @@ public class BookcasePresenter implements BasePresenter {
return false; return false;
} }
private void addLocalBook() {
XXPermissions.with(mMainActivity)
.permission(APPCONST.STORAGE_PERMISSIONS)
.request(new OnPermissionCallback() {
@Override
public void onGranted(List<String> permissions, boolean all) {
Intent fileSystemIntent = new Intent(mMainActivity, FileSystemActivity.class);
mMainActivity.startActivity(fileSystemIntent);
}
@Override
public void onDenied(List<String> permissions, boolean never) {
ToastUtils.showWarring("储存权限被拒绝,无法添加本地书籍!");
}
});
}
/** /**
* 显示书籍分组菜单 * 显示书籍分组菜单
*/ */
@ -554,7 +561,7 @@ public class BookcasePresenter implements BasePresenter {
if (canEditBookcase()) { if (canEditBookcase()) {
mMainActivity.getViewPagerMain().setEnableScroll(false); mMainActivity.getViewPagerMain().setEnableScroll(false);
mBookcaseFragment.getSrlContent().setEnableRefresh(false); mBookcaseFragment.getSrlContent().setEnableRefresh(false);
if (mSetting.getSortStyle() == 0){ if (mSetting.getSortStyle() == 0) {
ToastUtils.showInfo("长按可移动书籍哦!"); ToastUtils.showInfo("长按可移动书籍哦!");
} }
itemTouchCallback.setLongPressDragEnable(mSetting.getSortStyle() == 0); itemTouchCallback.setLongPressDragEnable(mSetting.getSortStyle() == 0);
@ -690,7 +697,7 @@ public class BookcasePresenter implements BasePresenter {
} }
//加入分组 //加入分组
public void addGroup(Book book){ public void addGroup(Book book) {
mBookGroupDia.addGroup(book, new BookGroupDialog.OnGroup() { mBookGroupDia.addGroup(book, new BookGroupDialog.OnGroup() {
@Override @Override
public void change() { public void change() {
@ -884,7 +891,6 @@ public class BookcasePresenter implements BasePresenter {
} }
/** /**
* 发送通知 * 发送通知
*/ */

@ -1,31 +0,0 @@
package xyz.fycz.myreader.util;
import android.content.Context;
import android.content.pm.PackageManager;
import androidx.core.content.ContextCompat;
public class PermissionsChecker {
private final Context mContext;
public PermissionsChecker(Context context) {
mContext = context.getApplicationContext();
}
// 判断权限集合
public boolean lacksPermissions(String... permissions) {
for (String permission : permissions) {
if (lacksPermission(permission)) {
return true;
}
}
return false;
}
// 判断是否缺少权限
private boolean lacksPermission(String permission) {
return ContextCompat.checkSelfPermission(mContext, permission) ==
PackageManager.PERMISSION_DENIED;
}
}

@ -33,6 +33,7 @@ import xyz.fycz.myreader.util.utils.OkHttpUtils;
import xyz.fycz.myreader.util.utils.StringUtils; import xyz.fycz.myreader.util.utils.StringUtils;
@Keep @Keep
@SuppressWarnings({"unused"}) @SuppressWarnings({"unused"})
public interface JsExtensions { public interface JsExtensions {
String TAG = JsExtensions.class.getSimpleName(); String TAG = JsExtensions.class.getSimpleName();

@ -72,6 +72,10 @@ public class FileUtils {
return file; return file;
} }
public static String getDataDir(){
return getFileDir().getParent();
}
//获取Cache文件夹 //获取Cache文件夹
public static String getCachePath(){ public static String getCachePath(){
if (isSdCardExist()){ if (isSdCardExist()){

@ -492,7 +492,10 @@
<string name="dyys">段友影视,超清无水印广告视频站</string> <string name="dyys">段友影视,超清无水印广告视频站</string>
<string name="all_read_time">总阅读时间:%s</string> <string name="all_read_time">总阅读时间:%s</string>
<string name="read_record">阅读记录</string> <string name="read_record">阅读记录</string>
<string name="privacy_tip">\n感谢您使用风月读书APP!\n我们非常重视您的个人信息和隐私保护。为了更好地保障您的个人权益,在您使用我们的产品前,请务必审慎阅读《隐私政策》内的所有条款,当您点击“同意并继续”即表示您己阅读完毕并同意以上协议的全部内容,开始使用我们的产品和服务。</string> <string name="privacy_tip">\n感谢您使用风月读书APP!
\n\n1.我们非常重视您的个人信息和隐私保护。为了更好地保障您的个人权益,在您使用我们的产品前,请务必审慎阅读《隐私政策》内的所有条款.
\n\n2.我们可能会申请存储权限,以实现下载、分享、备份、应用升级、导入本地书籍等相关功能.
\n\n如果您己阅读完毕并同意以上协议的全部内容,请点击下方“同意并继续”按钮以开始使用我们的产品和服务.</string>
<string name="close">关闭</string> <string name="close">关闭</string>
<string name="official_web">官网</string> <string name="official_web">官网</string>
<string name="privacy_policy">隐私政策</string> <string name="privacy_policy">隐私政策</string>

@ -1,2 +1,2 @@
#Fri Jun 04 20:20:53 CST 2021 #Sun Jun 06 10:44:17 CST 2021
VERSION_CODE=208 VERSION_CODE=210

Loading…
Cancel
Save