pull/5/head v2.0.0
fengyuecanzhu 3 years ago
parent 9411c907a0
commit f917091289
  1. 4
      .idea/assetWizardSettings.xml
  2. 10
      app/src/main/assets/updatelog.fy
  3. 14
      app/src/main/java/xyz/fycz/myreader/application/CrashHandler.java
  4. 1
      app/src/main/java/xyz/fycz/myreader/common/URLCONST.java
  5. 77
      app/src/main/java/xyz/fycz/myreader/ui/activity/AboutActivity.java
  6. 36
      app/src/main/java/xyz/fycz/myreader/util/OpenFileHelper.java
  7. 6
      app/src/main/java/xyz/fycz/myreader/util/utils/AdUtils.java
  8. 34
      app/src/main/java/xyz/fycz/myreader/util/utils/OkHttpUtils.java
  9. 9
      app/src/main/res/drawable/ic___.xml
  10. 9
      app/src/main/res/drawable/ic_upload.xml
  11. 36
      app/src/main/res/layout/layout_about_content.xml
  12. 1
      app/src/main/res/values/strings.xml

@ -14,8 +14,8 @@
<option name="values">
<map>
<entry key="assetSourceType" value="FILE" />
<entry key="outputName" value="ic_source" />
<entry key="sourceFile" value="F:\SVG图标\代码.svg" />
<entry key="outputName" value="ic___" />
<entry key="sourceFile" value="F:\SVG图标\上传.svg" />
</map>
</option>
</PersistentState>

@ -1,5 +1,13 @@
2021.05.16
风月读书v2.0.0
更新内容:
1、优化第三方书源(之前beta版本导入的第三方书源需要重新导入)
2、修复已知bug
3、新增崩溃日志记录
4、关于界面新增崩溃日志分享
2021.05.15
风月读书v1.9.8-beta
风月读书v1.9.9-beta
更新内容:
1、修复搜索闪退的bug

@ -18,6 +18,8 @@ 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;
@ -29,9 +31,14 @@ 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.SplashActivity;
import xyz.fycz.myreader.util.utils.FileUtils;
import xyz.fycz.myreader.util.utils.OkHttpUtils;
/**
* @author fengyue
@ -40,6 +47,7 @@ import xyz.fycz.myreader.util.utils.FileUtils;
public final class CrashHandler implements Thread.UncaughtExceptionHandler {
private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
/**
* 注册 Crash 监听
*/
@ -62,14 +70,11 @@ public final class CrashHandler implements Thread.UncaughtExceptionHandler {
@SuppressLint("ApplySharedPref")
@Override
public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) {
saveCrashLog(throwable);
// 不去触发系统的崩溃处理(com.android.internal.os.RuntimeInit$KillApplicationHandler)
if (mNextHandler != null && !mNextHandler.getClass().getName().startsWith("com.android.internal.os")) {
mNextHandler.uncaughtException(thread, throwable);
}
// 杀死进程(这个事应该是系统干的,但是它会多弹出一个崩溃对话框,所以需要我们自己手动杀死进程)
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(10);
@ -135,7 +140,8 @@ public final class CrashHandler implements Thread.UncaughtExceptionHandler {
String time = formatter.format(new Date());
String fileName = "crash-" + time + "-" + timestamp + ".log";
String path = APPCONST.LOG_DIR + fileName;
FileUtils.writeText(mPhoneInfo + "\n\n" + mStackTrace, FileUtils.getFile(path));
File file = FileUtils.getFile(path);
FileUtils.writeText(mPhoneInfo + "\n\n" + mStackTrace, file);
}
/**

@ -21,6 +21,7 @@ public class URLCONST {
public static final String FY_READER_URL = "https://fyreader.fycz.tk";
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 DONATE = "https://gitee.com/fengyuecanzhu/Donate/raw/master";

@ -8,15 +8,27 @@ import android.net.Uri;
import androidx.appcompat.widget.Toolbar;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import xyz.fycz.myreader.R;
import xyz.fycz.myreader.application.App;
import xyz.fycz.myreader.base.BaseActivity;
import xyz.fycz.myreader.base.observer.MyObserver;
import xyz.fycz.myreader.common.APPCONST;
import xyz.fycz.myreader.common.URLCONST;
import xyz.fycz.myreader.databinding.ActivityAboutBinding;
import xyz.fycz.myreader.ui.dialog.DialogCreator;
import xyz.fycz.myreader.util.ShareUtils;
import xyz.fycz.myreader.util.SharedPreUtils;
import xyz.fycz.myreader.util.ToastUtils;
import xyz.fycz.myreader.util.ZipUtils;
import xyz.fycz.myreader.util.utils.FileUtils;
import xyz.fycz.myreader.util.utils.OkHttpUtils;
import xyz.fycz.myreader.util.utils.RxUtils;
/**
* @author fengyue
@ -61,8 +73,9 @@ public class AboutActivity extends BaseActivity {
SharedPreUtils.getInstance().getString(getString(R.string.downloadLink), URLCONST.LAN_ZOUS_URL)));
binding.il.vwUpdate.setOnClickListener(v -> App.checkVersionByServer(this, true));
binding.il.vwUpdateLog.setOnClickListener(v -> DialogCreator.createAssetTipDialog(this, "更新日志", "updatelog.fy"));
binding.il.vwShareLog.setOnClickListener(v -> shareCrashLog());
binding.il.vwQq.setOnClickListener(v -> {
if (!App.joinQQGroup(this,"8PIOnHFuH6A38hgxvD_Rp2Bu-Ke1ToBn")){
if (!App.joinQQGroup(this, "8PIOnHFuH6A38hgxvD_Rp2Bu-Ke1ToBn")) {
//数据
ClipData mClipData = ClipData.newPlainText("Label", "1085028304");
//把数据设置到剪切板上
@ -73,7 +86,6 @@ public class AboutActivity extends BaseActivity {
});
binding.il.vwGit.setOnClickListener(v -> openIntent(Intent.ACTION_VIEW, getString(R.string.this_github_url)));
binding.il.vwDisclaimer.setOnClickListener(v -> DialogCreator.createAssetTipDialog(this, "免责声明", "disclaimer.fy"));
}
void openIntent(String intentName, String address) {
@ -87,4 +99,65 @@ public class AboutActivity extends BaseActivity {
}
private void updateCrashLog() {
File logDir = new File(APPCONST.LOG_DIR);
if (!logDir.exists() || logDir.listFiles() == null || logDir.listFiles().length == 0) {
ToastUtils.showWarring("没有日志文件");
return;
}
Observable.create((ObservableOnSubscribe<String>) emitter -> {
String time = String.valueOf(System.currentTimeMillis());
String fileName = "log-" + time + ".zip";
String logZip = FileUtils.getCachePath() + File.separator + fileName;
File zipFile = FileUtils.getFile(logZip);
if (ZipUtils.zipFile(logDir, zipFile)) {
emitter.onNext(OkHttpUtils.upload(URLCONST.LOG_UPLOAD_URL, logZip, fileName));
} else {
emitter.onError(new Throwable("日志文件压缩失败"));
}
emitter.onComplete();
}).compose(RxUtils::toSimpleSingle).subscribe(new MyObserver<String>() {
@Override
public void onNext(@NotNull String s) {
ToastUtils.showInfo(s);
}
@Override
public void onError(Throwable e) {
ToastUtils.showError(e.getLocalizedMessage());
}
});
}
private void shareCrashLog() {
File logDir = new File(APPCONST.LOG_DIR);
if (!logDir.exists() || logDir.listFiles() == null || logDir.listFiles().length == 0) {
ToastUtils.showWarring("没有日志文件");
return;
}
Observable.create((ObservableOnSubscribe<File>) emitter -> {
String time = String.valueOf(System.currentTimeMillis());
String fileName = "log-" + time + ".zip";
String logZip = FileUtils.getCachePath() + File.separator + fileName;
File zipFile = FileUtils.getFile(logZip);
if (ZipUtils.zipFile(logDir, zipFile)) {
emitter.onNext(zipFile);
} else {
emitter.onError(new Throwable("日志文件压缩失败"));
}
emitter.onComplete();
}).compose(RxUtils::toSimpleSingle).subscribe(new MyObserver<File>() {
@Override
public void onNext(@NotNull File file) {
ShareUtils.share(AboutActivity.this, file, file.getName(), "application/x-zip-compressed");
}
@Override
public void onError(Throwable e) {
ToastUtils.showError(e.getLocalizedMessage());
}
});
}
}

@ -6,9 +6,8 @@ import android.content.Intent;
import java.io.File;
public class OpenFileHelper {
private final static String[][] MIME_MapTable={
private final static String[][] MIME_MapTable = {
//{后缀名,MIME类型}
{".3gp", "video/3gpp"},
{".apk", "application/vnd.android.package-archive"},
@ -80,23 +79,24 @@ public class OpenFileHelper {
/**
* 打开文件
*
* @param file
*/
public static void openFile(Context context,File file){
public static void openFile(Context context, File file) {
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//设置intent的Action属性
//设置intent的Action属性
intent.setAction(Intent.ACTION_VIEW);
//获取文件file的MIME类型
//获取文件file的MIME类型
String type = getMIMEType(file);
//设置intent的data和Type属性。
intent.setDataAndType(/*uri*/UriFileUtil.getUriForFile(context,file), type);
//跳转
//设置intent的data和Type属性。
intent.setDataAndType(/*uri*/UriFileUtil.getUriForFile(context, file), type);
//跳转
try {
context.startActivity(intent); //这里最好try一下,有可能会报错。 比如说你的MIME类型是打开邮箱,但是你手机里面没装邮箱客户端,就会报错。
}catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
ToastUtils.showError("没有安装相应的文件读取工具或者文件错误");
}
@ -104,26 +104,26 @@ public class OpenFileHelper {
}
/**
* 根据文件后缀名获得对应的MIME类型
*
* @param file
*/
private static String getMIMEType(File file) {
String type="*/*";
String type = "*/*";
String fName = file.getName();
//获取后缀名前的分隔符"."在fName中的位置。
int dotIndex = fName.lastIndexOf(".");
if(dotIndex < 0){
if (dotIndex < 0) {
return type;
}
/* 获取文件的后缀名*/
String end=fName.substring(dotIndex,fName.length()).toLowerCase();
if(end=="")return type;
//在MIME和文件类型的匹配表中找到对应的MIME类型。
for(int i=0;i<MIME_MapTable.length;i++){ //MIME_MapTable??在这里你一定有疑问,这个MIME_MapTable是什么?
if(end.equals(MIME_MapTable[i][0]))
/* 获取文件的后缀名*/
String end = fName.substring(dotIndex).toLowerCase();
if (end.equals("")) return type;
//在MIME和文件类型的匹配表中找到对应的MIME类型。
for (int i = 0; i < MIME_MapTable.length; i++) { //MIME_MapTable??在这里你一定有疑问,这个MIME_MapTable是什么?
if (end.equals(MIME_MapTable[i][0]))
type = MIME_MapTable[i][1];
}
return type;

@ -123,9 +123,9 @@ public class AdUtils {
public static void initAd() {
if (!hasInitAd) {
hasInitAd = true;
DdSdkHelper.init("1234", "216", "51716a16fbdf50905704b6575b1b3b60",
"142364", "35ce0efe5f3cc960b116db227498e238",
"8167", "85bd159309c3da1b",
DdSdkHelper.init("", "", "",
"", "",
"", "",
App.getApplication(), App.isDebug());
}
}

@ -15,6 +15,7 @@ import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
@ -22,10 +23,12 @@ import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import okhttp3.Request;
@ -89,7 +92,7 @@ public class OkHttpUtils {
return "";
} else {
String bodyStr = new String(body.bytes(), Charset.forName(encodeType));
Log.d("Http: read finish", bodyStr);
Log.d("Http -> read finish", bodyStr);
return bodyStr;
}
}
@ -180,7 +183,7 @@ public class OkHttpUtils {
String content = jsonObj.getString("content");
Document doc = Jsoup.parse(content);
content = doc.text();
Log.d("Http: UpdateInfo", content);
Log.d("Http -> UpdateInfo", content);
return content;
}
}
@ -322,4 +325,31 @@ public class OkHttpUtils {
this.content = content;
}
}
public static String upload(String url, String filePath, String fileName) throws IOException {
OkHttpClient client = getOkHttpClient();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", fileName,
RequestBody.create(MediaType.parse("multipart/form-data"), new File(filePath)))
.build();
Request request = new Request.Builder()
.header("Authorization", "Client-ID " + UUID.randomUUID())
.url(url)
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
ResponseBody body = response.body();
if (body == null) {
return "";
} else {
String bodyStr = new String(body.bytes(), StandardCharsets.UTF_8);
Log.d("Http -> upload finish", bodyStr);
return bodyStr;
}
}
}

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FF000000"
android:pathData="M512,960C265.6,960 64,758.4 64,512S265.6,64 512,64s448,201.6 448,448 -201.6,448 -448,448zM512,128c-211.2,0 -384,172.8 -384,384s172.8,384 384,384 384,-172.8 384,-384 -172.8,-384 -384,-384zM512,800c-17.6,0 -32,-14.4 -32,-32L480,480c0,-17.6 14.4,-32 32,-32s32,14.4 32,32v288c0,17.6 -14.4,32 -32,32zM672,672L352,672c-17.6,0 -32,-14.4 -32,-32s14.4,-32 32,-32h320c17.6,0 32,14.4 32,32s-14.4,32 -32,32zM672,512L352,512c-17.6,0 -32,-14.4 -32,-32s14.4,-32 32,-32h320c17.6,0 32,14.4 32,32s-14.4,32 -32,32zM512,512c-8,0 -16,-3.2 -22.4,-9.6L331.2,344c-12.8,-12.8 -12.8,-32 0,-44.8 12.8,-12.8 32,-12.8 44.8,0l158.4,158.4c12.8,12.8 12.8,32 0,44.8 -6.4,6.4 -14.4,9.6 -22.4,9.6zM512,512c-8,0 -16,-3.2 -22.4,-9.6 -12.8,-12.8 -12.8,-32 0,-44.8L648,299.2c12.8,-12.8 32,-12.8 44.8,0 12.8,12.8 12.8,32 0,44.8L534.4,502.4C528,508.8 520,512 512,512z"/>
</vector>

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M926.5,495.96c0,159.9 -120.82,291.59 -276.14,308.76v-69.59c117.1,-16.74 207.11,-117.45 207.11,-239.17 0,-133.44 -108.18,-241.62 -241.62,-241.62 -121.7,0 -222.29,90.04 -239.05,207.11h-71.61c-76.25,0 -138.07,61.81 -138.07,138.07 0,57.19 34.77,106.26 84.33,127.23 16.52,6.98 34.68,10.85 53.74,10.85h138.07v69.04h-137.4c-0.23,0 -0.44,0.02 -0.67,0.02 -114.38,0 -207.11,-92.73 -207.11,-207.11 0,-114.39 92.73,-207.11 207.11,-207.11h17.76C365.6,271.76 480.59,185.3 615.84,185.3c171.56,0 310.66,139.09 310.66,310.66zM674.76,623.93c13.48,-13.47 13.48,-35.33 0,-48.81L571.21,471.57c-6.47,-6.47 -15.25,-10.11 -24.4,-10.11s-17.93,3.64 -24.4,10.11L418.84,575.12c-13.48,13.48 -13.48,35.34 0,48.81 13.47,13.48 35.33,13.48 48.81,0l44.63,-44.62v227.32c0,19.06 15.46,34.52 34.52,34.52s34.52,-15.46 34.52,-34.52V579.31l44.63,44.62c13.47,13.48 35.33,13.48 48.81,0z"
android:fillColor="#040000"/>
</vector>

@ -279,6 +279,42 @@
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/vw_share_log"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_margin="6dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
app:cardBackgroundColor="@color/background_card">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_upload"
app:tint="@color/textSecondary" />
<TextView
android:id="@+id/tv_share_log"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:text="@string/share_log"
android:textColor="@color/textSecondary" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/vw_disclaimer"
android:layout_width="match_parent"

@ -102,6 +102,7 @@
<string name="share_app">分享软件</string>
<string name="update_log">更新日志</string>
<string name="git_hub">GitHub</string>
<string name="share_log">分享崩溃日志</string>
<string name="email">邮箱:fy@fycz.xyz</string>
<string name="this_github_url">https://github.com/fengyuecanzhu/FYReader</string>
<string name="update">检查更新</string>

Loading…
Cancel
Save