Skip to content

Commit 5d24c59

Browse files
committed
Support logging
1 parent 06812ce commit 5d24c59

File tree

4 files changed

+187
-0
lines changed

4 files changed

+187
-0
lines changed

app/src/main/java/com/surcumference/fingerprint/Lang.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ public static String getString(int res) {
121121
return tr("通用设置", "一般选项", "General");
122122
case R.id.settings_title_use_biometric_api:
123123
return tr("使用 Biometric Api", "使用 Biometric Api", "Use Biometric Api");
124+
case R.id.settings_title_start_logcat:
125+
return tr("开始记录日志", "開始記錄日誌", "Start logging");
126+
case R.id.settings_title_stop_logcat:
127+
return tr("停止记录日志", "停止記錄日誌", "Stop logging");
124128
case R.id.settings_sub_title_switch_alipay:
125129
return tr("启用支付宝指纹支付", "啟用支付宝指紋支付", "Enable fingerprint payment for Alipay");
126130
case R.id.settings_sub_title_switch_wechat:
@@ -147,6 +151,10 @@ public static String getString(int res) {
147151
return tr("将同时升级以下模块", "將同時升級以下模塊", "The following modules will be upgraded at the same time");
148152
case R.id.settings_sub_title_use_biometric_api:
149153
return tr("实验性, 仅 Android 9+ 可用", "實驗性, 僅 Android 9+ 可用", "Experimental, available only on Android 9+");
154+
case R.id.settings_sub_title_start_logcat:
155+
return tr("开始 --> 你的表演 --> 停止 --> 发送给开发者", "開始 --> 你的表演 --> 停止 --> 發送給開發者", "Start --> Payment operation --> Stop --> Send to developer");
156+
case R.id.settings_sub_title_stop_logcat:
157+
return tr("开始 --> 你的表演 --> 停止 --> 发送给开发者", "開始 --> 你的表演 --> 停止 --> 發送給開發者", "Start --> Payment operation --> Stop --> Send to developer");
150158
case R.id.fingerprint_verification:
151159
return tr("请验证指纹", "請驗證指紋", "Fingerprint verification");
152160
case R.id.wechat_general:
@@ -230,6 +238,10 @@ public static String getString(int res) {
230238
return tr("调用QQ捐赠页失败, 您可以手动转账捐赠哦, 账号: " + Constant.AUTHOR_QQ, "調用QQ捐贈頁失敗, 您可以手動轉賬捐贈哦, 帳號: " + Constant.AUTHOR_QQ, "Can't jump to QQ donate page, You can do it manually by transfer to account: " + Constant.AUTHOR_QQ);
231239
case R.id.toast_need_qq_7_2_5:
232240
return tr("您的QQ版本过低, 不支持指纹功能, 请升级至7.2.5以上的版本", "您的QQ版本過低, 不支持指紋功能, 請升級至7.2.5以上的版本", "Your QQ version is too low, does not support the fingerprint function, please upgrade to version 7.2.5 and above");
241+
case R.id.toast_start_logging:
242+
return tr("请开始你的表演, 日志已开始记录\n日志路径: %s", "請開始你的表演, 日誌已開始記錄\n日誌路徑: %s", "Star logging\nlog path: %s");
243+
case R.id.toast_stop_logging:
244+
return tr("表演结束, 请将日志文件分享给开发者\n日志路径: %s", "表演结束, 请将日志文件分享给开发者\n日誌路徑: %s", "Stop logging\nlog path: %s");
233245
case R.id.template:
234246
return tr("", "", "");
235247
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package com.surcumference.fingerprint.util;
2+
3+
import com.surcumference.fingerprint.util.log.L;
4+
5+
import java.io.BufferedReader;
6+
import java.io.File;
7+
import java.io.InputStreamReader;
8+
import java.io.PrintWriter;
9+
import java.lang.reflect.Field;
10+
import java.util.concurrent.Executors;
11+
import java.util.concurrent.ScheduledExecutorService;
12+
import java.util.concurrent.TimeUnit;
13+
14+
public class LogcatManager {
15+
private Process process;
16+
private final File targetFile;
17+
private ScheduledExecutorService timeOutExecutor = Executors.newScheduledThreadPool(1);
18+
19+
public LogcatManager(File targetFile) {
20+
this.targetFile = targetFile;
21+
}
22+
23+
public void startLogging(long timeOutMS) {
24+
synchronized (LogcatManager.class) {
25+
try {
26+
stopLoggingInternal();
27+
this.process = Runtime.getRuntime().exec("logcat");
28+
Task.onBackground(() -> {
29+
PrintWriter pw = null;
30+
try {
31+
pw = new PrintWriter(targetFile);
32+
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
33+
String line;
34+
while ((line = bufferedReader.readLine()) != null) {
35+
pw.println(line);
36+
}
37+
} catch (Exception e) {
38+
L.e(e);
39+
} finally {
40+
FileUtils.closeCloseable(pw);
41+
}
42+
});
43+
timeOutExecutor.shutdown();
44+
timeOutExecutor = Executors.newScheduledThreadPool(1);
45+
timeOutExecutor.schedule(() -> {
46+
stopLoggingInternal();
47+
L.d("stopLogging on timeout");
48+
}, timeOutMS, TimeUnit.MILLISECONDS);
49+
L.d("startLogging timeOutMS", timeOutMS);
50+
} catch (Exception e) {
51+
L.e(e);
52+
}
53+
}
54+
}
55+
56+
public void stopLogging() {
57+
synchronized (LogcatManager.class) {
58+
stopLoggingInternal();
59+
L.d("stopLogging");
60+
}
61+
}
62+
63+
private void stopLoggingInternal() {
64+
try {
65+
if (!isRunning()) {
66+
return;
67+
}
68+
int pid = getPid(process);
69+
if (pid > -1) {
70+
android.os.Process.killProcess(pid);
71+
}
72+
process.destroyForcibly();
73+
} catch (Exception e) {
74+
L.e(e);
75+
} finally {
76+
timeOutExecutor.shutdown();
77+
timeOutExecutor = Executors.newScheduledThreadPool(1);
78+
}
79+
}
80+
81+
public boolean isRunning() {
82+
Process process = this.process;
83+
if (process == null) {
84+
return false;
85+
}
86+
return process.isAlive();
87+
}
88+
89+
public File getTargetFile() {
90+
return this.targetFile;
91+
}
92+
93+
public static int getPid(Process p) {
94+
try {
95+
Field f = p.getClass().getDeclaredField("pid");
96+
f.setAccessible(true);
97+
return f.getInt(p);
98+
} catch (Throwable e) {
99+
L.e(e);
100+
}
101+
return -1;
102+
}
103+
}

app/src/main/java/com/surcumference/fingerprint/view/AdvanceSettingsView.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.surcumference.fingerprint.view;
22

33
import android.content.Context;
4+
import android.content.Intent;
45
import android.graphics.Color;
56
import android.graphics.drawable.ColorDrawable;
67
import android.util.AttributeSet;
@@ -13,14 +14,23 @@
1314
import androidx.annotation.NonNull;
1415
import androidx.annotation.Nullable;
1516

17+
import com.hjq.toast.Toaster;
1618
import com.surcumference.fingerprint.Lang;
1719
import com.surcumference.fingerprint.R;
1820
import com.surcumference.fingerprint.adapter.PreferenceAdapter;
1921
import com.surcumference.fingerprint.util.Config;
22+
import com.surcumference.fingerprint.util.DateUtils;
2023
import com.surcumference.fingerprint.util.DpUtils;
24+
import com.surcumference.fingerprint.util.FileUtils;
25+
import com.surcumference.fingerprint.util.LogcatManager;
26+
import com.surcumference.fingerprint.util.Task;
27+
import com.surcumference.fingerprint.util.log.L;
2128

29+
import java.io.File;
2230
import java.util.ArrayList;
31+
import java.util.Date;
2332
import java.util.List;
33+
import java.util.Locale;
2434

2535

2636
/**
@@ -33,6 +43,8 @@ public class AdvanceSettingsView extends DialogFrameLayout implements AdapterVie
3343
private PreferenceAdapter mListAdapter;
3444
private ListView mListView;
3545

46+
private static LogcatManager sLogcatManager;
47+
3648
public AdvanceSettingsView(@NonNull Context context) {
3749
super(context);
3850
init(context);
@@ -49,6 +61,17 @@ public AdvanceSettingsView(@NonNull Context context, @Nullable AttributeSet attr
4961
}
5062

5163
private void init(Context context) {
64+
if (sLogcatManager == null) {
65+
File logFile = FileUtils.getSharableFile(context, "flog/" + context.getPackageName() + ".log");
66+
try {
67+
FileUtils.delete(logFile.getParentFile());
68+
logFile.getParentFile().mkdirs();
69+
} catch (Exception e) {
70+
L.e(e);
71+
}
72+
sLogcatManager = new LogcatManager(logFile);
73+
sLogcatManager.getTargetFile().deleteOnExit();
74+
}
5275
LinearLayout rootVerticalLayout = new LinearLayout(context);
5376
rootVerticalLayout.setOrientation(LinearLayout.VERTICAL);
5477

@@ -65,6 +88,11 @@ private void init(Context context) {
6588
mListView.setDivider(new ColorDrawable(Color.TRANSPARENT));
6689
mSettingsDataList.add(new PreferenceAdapter.Data(Lang.getString(R.id.settings_title_no_fingerprint_icon), Lang.getString(R.id.settings_sub_title_no_fingerprint_icon), true, Config.from(context).isShowFingerprintIcon()));
6790
mSettingsDataList.add(new PreferenceAdapter.Data(Lang.getString(R.id.settings_title_use_biometric_api), Lang.getString(R.id.settings_sub_title_use_biometric_api), true, Config.from(context).isUseBiometricApi()));
91+
if (sLogcatManager.isRunning()) {
92+
mSettingsDataList.add(new PreferenceAdapter.Data(Lang.getString(R.id.settings_title_stop_logcat), Lang.getString(R.id.settings_sub_title_stop_logcat)));
93+
} else {
94+
mSettingsDataList.add(new PreferenceAdapter.Data(Lang.getString(R.id.settings_title_start_logcat), Lang.getString(R.id.settings_sub_title_start_logcat)));
95+
}
6896
mListAdapter = new PreferenceAdapter(mSettingsDataList);
6997

7098
rootVerticalLayout.addView(lineView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, DpUtils.dip2px(context, 2)));
@@ -102,7 +130,45 @@ public void onItemClick(AdapterView<?> adapterView, View view, int position, lon
102130
data.selectionState = !data.selectionState;
103131
config.setUseBiometricApi(data.selectionState);
104132
mListAdapter.notifyDataSetChanged();
133+
} else if (Lang.getString(R.id.settings_title_start_logcat).equals(data.title)) {
134+
sLogcatManager.startLogging(5 * 60 * 1000 /** 5min */);
135+
data.title = Lang.getString(R.id.settings_title_stop_logcat);
136+
data.subTitle = Lang.getString(R.id.settings_sub_title_stop_logcat);
137+
mListAdapter.notifyDataSetChanged();
138+
File logFile = sLogcatManager.getTargetFile();
139+
Toaster.showLong(String.format(Locale.getDefault(),
140+
Lang.getString(R.id.toast_start_logging), logFile.getAbsoluteFile()));
141+
} else if (Lang.getString(R.id.settings_title_stop_logcat).equals(data.title)) {
142+
sLogcatManager.stopLogging();
143+
data.title = Lang.getString(R.id.settings_title_start_logcat);
144+
data.subTitle = Lang.getString(R.id.settings_sub_title_start_logcat);
145+
mListAdapter.notifyDataSetChanged();
146+
File logFile = sLogcatManager.getTargetFile();
147+
try {
148+
File logShareFile = new File(logFile.getParentFile(), context.getPackageName() + "-" + DateUtils.toString(new Date()).replaceAll("[: ]", "-") + ".log");
149+
if (logFile.renameTo(logShareFile)) {
150+
logFile = logShareFile;
151+
}
152+
} catch (Exception e) {
153+
L.e(e);
154+
}
155+
logFile.deleteOnExit();
156+
File finalLogFile = logFile;
157+
Task.onMain(500, () -> Toaster.showLong(String.format(Locale.getDefault(),
158+
Lang.getString(R.id.toast_stop_logging), finalLogFile.getAbsoluteFile())));
159+
shareFile(logFile);
105160
}
106161
}
107162

163+
private void shareFile(File targetFile) {
164+
try {
165+
Context context = getContext();
166+
Intent intent = new Intent(Intent.ACTION_SEND);
167+
intent.setType("*/*");
168+
intent.putExtra(Intent.EXTRA_STREAM, FileUtils.getUri(context, targetFile));
169+
context.startActivity(Intent.createChooser(intent, "Share File"));
170+
} catch (Exception e) {
171+
L.e(e);
172+
}
173+
}
108174
}

app/src/main/res/values/ids.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
<item name="settings_title_no_fingerprint_icon" type="id"/>
4646
<item name="settings_title_donate" type="id"/>
4747
<item name="settings_title_use_biometric_api" type="id"/>
48+
<item name="settings_title_start_logcat" type="id"/>
49+
<item name="settings_title_stop_logcat" type="id"/>
4850
<item name="settings_sub_title_switch_alipay" type="id"/>
4951
<item name="settings_sub_title_switch_wechat" type="id"/>
5052
<item name="settings_sub_title_switch_qq" type="id"/>
@@ -58,6 +60,8 @@
5860
<item name="settings_sub_title_advance" type="id"/>
5961
<item name="settings_sub_title_update_modules_same_time" type="id"/>
6062
<item name="settings_sub_title_use_biometric_api" type="id"/>
63+
<item name="settings_sub_title_start_logcat" type="id"/>
64+
<item name="settings_sub_title_stop_logcat" type="id"/>
6165
<item name="fingerprint_verification" type="id"/>
6266
<item name="wechat_general" type="id"/>
6367
<item name="app_settings_name" type="id"/>
@@ -100,6 +104,8 @@
100104
<item name="toast_goto_donate_page_fail_wechat" type="id"/>
101105
<item name="toast_goto_donate_page_fail_qq" type="id"/>
102106
<item name="toast_need_qq_7_2_5" type="id"/>
107+
<item name="toast_start_logging" type="id"/>
108+
<item name="toast_stop_logging" type="id"/>
103109

104110
<item name="tag_password_layout_listener" type="id"/>
105111
</resources>

0 commit comments

Comments
 (0)