add new func of logcatch
This commit is contained in:
1
modules/mogo-module-monitor/.gitignore
vendored
1
modules/mogo-module-monitor/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/build
|
||||
@@ -1,58 +0,0 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'kotlin-android'
|
||||
id 'kotlin-android-extensions'
|
||||
id 'kotlin-kapt'
|
||||
id 'com.alibaba.arouter'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.android.compileSdkVersion
|
||||
// buildToolsVersion rootProject.ext.android.buildToolsVersion
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.android.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.android.targetSdkVersion
|
||||
versionCode Integer.valueOf(VERSION_CODE)
|
||||
versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION")
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles 'consumer-rules.pro'
|
||||
//ARouter apt 参数
|
||||
kapt {
|
||||
useBuildCache = false
|
||||
arguments {
|
||||
arg("AROUTER_MODULE_NAME", project.getName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation rootProject.ext.dependencies.androidxappcompat
|
||||
implementation rootProject.ext.dependencies.androidxconstraintlayout
|
||||
|
||||
implementation rootProject.ext.dependencies.arouter
|
||||
kapt rootProject.ext.dependencies.aroutercompiler
|
||||
|
||||
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
|
||||
compileOnly rootProject.ext.dependencies.modulecommon
|
||||
} else {
|
||||
compileOnly project(':modules:mogo-module-common')
|
||||
}
|
||||
}
|
||||
|
||||
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()
|
||||
@@ -1 +0,0 @@
|
||||
-keep class com.zhidao.mogo.module.monitor.MogoMonitorConst.*{*;}
|
||||
@@ -1,3 +0,0 @@
|
||||
GROUP=com.mogo.module
|
||||
POM_ARTIFACT_ID=module-monitor
|
||||
VERSION_CODE=1
|
||||
21
modules/mogo-module-monitor/proguard-rules.pro
vendored
21
modules/mogo-module-monitor/proguard-rules.pro
vendored
@@ -1,21 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -1,5 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.zhidao.mogo.module.monitor">
|
||||
|
||||
/
|
||||
</manifest>
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.zhidao.mogo.module.monitor;
|
||||
|
||||
public class MogoMonitorConst {
|
||||
|
||||
private MogoMonitorConst(){}
|
||||
|
||||
public static final String MODULE_NAME = "MogoMonitor";
|
||||
public static final String MODULE_PATH = "/monitor/api";
|
||||
|
||||
public static final int LOG_PUSH_TYPE = 500000;
|
||||
|
||||
/**
|
||||
* 开始抓日志
|
||||
*/
|
||||
public static final int START_CATCH_LOG = 1;
|
||||
/**
|
||||
* 结束抓日志
|
||||
*/
|
||||
public static final int STOP_CATCH_LOG = 2;
|
||||
/**
|
||||
* 本应用设置,打开日志
|
||||
*/
|
||||
public static final int LOCAL_CONFIG_OPEN_LOG = 3;
|
||||
/**
|
||||
* 本应用设置,关闭日志
|
||||
*/
|
||||
public static final int LOCAL_CONFIG_CLOSE_LOG = 4;
|
||||
|
||||
public static final String BROADCAST_LOG_CTRL = "com.mogo.control.action.LOG_CTRL";
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.zhidao.mogo.module.monitor;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.mogo.service.monitor.IMogoMonitorLog;
|
||||
import com.mogo.service.monitor.IMogoMonitorProvider;
|
||||
import com.zhidao.mogo.module.monitor.log.MogoLogMonitor;
|
||||
|
||||
/**
|
||||
* 应用监控模块provider
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
@Route(path = MogoMonitorConst.MODULE_PATH)
|
||||
public class MogoMonitorProvider implements IMogoMonitorProvider {
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
MogoLogMonitor.getInstance().init(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMogoMonitorLog getMogoMonitorLog() {
|
||||
return MogoLogMonitor.getInstance();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.zhidao.mogo.module.monitor.bean;
|
||||
|
||||
public class RemoteLogPushContent {
|
||||
private int type;
|
||||
/**
|
||||
* 日志抓取时长,单位是分钟
|
||||
*/
|
||||
private int duration;
|
||||
private String cmd;
|
||||
private String pkgName;
|
||||
|
||||
public RemoteLogPushContent(){
|
||||
|
||||
}
|
||||
|
||||
public RemoteLogPushContent(int duration, String pkgName) {
|
||||
this.duration = duration;
|
||||
this.pkgName = pkgName;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getCmd() {
|
||||
return cmd;
|
||||
}
|
||||
|
||||
public void setCmd(String cmd) {
|
||||
this.cmd = cmd;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(int duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public String getPkgName() {
|
||||
return pkgName;
|
||||
}
|
||||
|
||||
public void setPkgName(String pkgName) {
|
||||
this.pkgName = pkgName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RemoteLogPushContent{" +
|
||||
"type=" + type +
|
||||
", duration=" + duration +
|
||||
", cmd='" + cmd + '\'' +
|
||||
", pkgName='" + pkgName + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.zhidao.mogo.module.monitor.dialog;
|
||||
|
||||
/**
|
||||
* Log调试对话框操作回调
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public interface ILogDialogListener {
|
||||
/**
|
||||
* 点击了开始抓日志
|
||||
*/
|
||||
void onLogStart();
|
||||
|
||||
/**
|
||||
* 点击了结束抓日志
|
||||
*/
|
||||
void onLogStop();
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.zhidao.mogo.module.monitor.dialog;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.mogo.module.common.dialog.BaseFloatDialog;
|
||||
import com.zhidao.mogo.module.monitor.R;
|
||||
|
||||
/**
|
||||
* 日志手动调用开始结束的对话框,兼容了智慧出行,覆盖adas浮窗
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class LogDebugDialog extends BaseFloatDialog {
|
||||
public LogDebugDialog(@NonNull Context context) {
|
||||
super(context);
|
||||
setContentView(R.layout.dialog_log_debug);
|
||||
findViewById(R.id.btnStart).setOnClickListener(v -> {
|
||||
if (dialogListener != null) {
|
||||
dialogListener.onLogStart();
|
||||
}
|
||||
dismiss();
|
||||
});
|
||||
findViewById(R.id.btnStop).setOnClickListener(v->{
|
||||
if (dialogListener != null) {
|
||||
dialogListener.onLogStop();
|
||||
}
|
||||
|
||||
dismiss();
|
||||
});
|
||||
findViewById(R.id.btnForceClearNotice).setOnClickListener(v->{
|
||||
dismiss();
|
||||
});
|
||||
findViewById(R.id.btnRetryFlow).setOnClickListener(v->{
|
||||
dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
private ILogDialogListener dialogListener;
|
||||
|
||||
public void setDialogListener(ILogDialogListener dialogListener) {
|
||||
this.dialogListener = dialogListener;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
package com.zhidao.mogo.module.monitor.log;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.commons.context.ContextHolderUtil;
|
||||
import com.mogo.commons.debug.DebugConfig;
|
||||
import com.mogo.eagle.core.network.NetConfig;
|
||||
import com.mogo.eagle.core.network.utils.GsonUtil;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.service.cloud.socket.IMogoOnMessageListener;
|
||||
import com.mogo.service.monitor.IMogoMonitorLog;
|
||||
import com.mogo.utils.logger.LogLevel;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
import com.zhidao.mogo.module.monitor.MogoMonitorConst;
|
||||
import com.zhidao.mogo.module.monitor.bean.RemoteLogPushContent;
|
||||
import com.zhidao.mogo.module.monitor.dialog.ILogDialogListener;
|
||||
import com.zhidao.mogo.module.monitor.dialog.LogDebugDialog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.zhidao.mogo.module.monitor.MogoMonitorConst.LOG_PUSH_TYPE;
|
||||
import static com.zhidao.mogo.module.monitor.MogoMonitorConst.MODULE_NAME;
|
||||
|
||||
public class MogoLogMonitor implements IMogoOnMessageListener<RemoteLogPushContent>, IMogoMonitorLog,
|
||||
ILogDialogListener, Handler.Callback {
|
||||
|
||||
private static final String TAG = MODULE_NAME + "-Log";
|
||||
|
||||
private static volatile MogoLogMonitor mogoLogMonitor;
|
||||
|
||||
private MogoLogMonitor() {
|
||||
|
||||
}
|
||||
|
||||
public static MogoLogMonitor getInstance() {
|
||||
if (mogoLogMonitor == null) {
|
||||
synchronized (MogoLogMonitor.class) {
|
||||
if (mogoLogMonitor == null) {
|
||||
mogoLogMonitor = new MogoLogMonitor();
|
||||
}
|
||||
}
|
||||
}
|
||||
return mogoLogMonitor;
|
||||
}
|
||||
|
||||
private static final int MSG_TRY_CLOSE_LOG = 1001;
|
||||
private static final String MANUAL_CATCH_PKG_NAME = "manual-catch-log";
|
||||
private LogDebugDialog logDebugDialog;
|
||||
private RemoteLogPushContent manualContent = new RemoteLogPushContent(60,
|
||||
MANUAL_CATCH_PKG_NAME);
|
||||
|
||||
private Handler handler = new Handler(this);
|
||||
|
||||
private List<String> catchingList = new ArrayList<>();
|
||||
|
||||
public void init(Context context) {
|
||||
MogoApisHandler.getInstance().getApis()
|
||||
.getSocketManagerApi(AbsMogoApplication.getApp().getApplicationContext())
|
||||
.registerOnMessageListener(LOG_PUSH_TYPE, this);
|
||||
startRemoteCtrl(context);
|
||||
}
|
||||
|
||||
private void startRemoteCtrl(Context context) {
|
||||
Intent intent = new Intent("com.mogo.remotecontrol.action");
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
ComponentName comp = new ComponentName("com.mogo.remotecontrol",
|
||||
"com.mogo.remotecontrol.RemoteCtrlService");
|
||||
intent.setComponent(comp);
|
||||
context.startService(intent);
|
||||
Logger.d(TAG, "startRemoteCtrl");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMessage(Message msg) {
|
||||
if (msg.what == MSG_TRY_CLOSE_LOG) {
|
||||
closeLoggerLevel();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<RemoteLogPushContent> target() {
|
||||
return RemoteLogPushContent.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMsgReceived(RemoteLogPushContent obj) {
|
||||
Logger.d(TAG, "收到push消息: " + obj);
|
||||
switch (obj.getType()) {
|
||||
case MogoMonitorConst.START_CATCH_LOG:
|
||||
if (!catchingList.contains(obj.getPkgName())) {
|
||||
startCatchLog(obj);
|
||||
}
|
||||
break;
|
||||
case MogoMonitorConst.STOP_CATCH_LOG:
|
||||
stopCatchLog(obj);
|
||||
break;
|
||||
case MogoMonitorConst.LOCAL_CONFIG_OPEN_LOG:
|
||||
openLoggerLevel();
|
||||
break;
|
||||
case MogoMonitorConst.LOCAL_CONFIG_CLOSE_LOG:
|
||||
closeLoggerLevel();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogStart() {
|
||||
// 这个是通过对话框点击开始的回调
|
||||
if (catchingList.contains(MANUAL_CATCH_PKG_NAME)) {
|
||||
Toast.makeText(ContextHolderUtil.getContext(), "已经在抓日志了", Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Logger.d(TAG, "开始抓取日志====");
|
||||
manualContent.setType(MogoMonitorConst.START_CATCH_LOG);
|
||||
startCatchLog(manualContent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogStop() {
|
||||
// 这个是通过对话框点击结束的回调
|
||||
Logger.d(TAG, "结束抓取日志====");
|
||||
manualContent.setType(MogoMonitorConst.STOP_CATCH_LOG);
|
||||
stopCatchLog(manualContent);
|
||||
}
|
||||
|
||||
public void sendCtrlBroadcast(RemoteLogPushContent content) {
|
||||
startRemoteCtrl(ContextHolderUtil.getContext());
|
||||
Intent intent = new Intent(MogoMonitorConst.BROADCAST_LOG_CTRL);
|
||||
intent.putExtra("content", GsonUtil.jsonFromObject(content));
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
Logger.d(TAG, "sendCtrlBroadcast: " + content);
|
||||
ContextHolderUtil.getContext().sendBroadcast(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 放开Logger的限制
|
||||
*/
|
||||
private void openLoggerLevel() {
|
||||
Logger.init(LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据状态收紧Logger的限制
|
||||
*/
|
||||
private void closeLoggerLevel() {
|
||||
if (!catchingList.isEmpty()) {
|
||||
Logger.init(DebugConfig.isDebug() ? LogLevel.DEBUG : LogLevel.OFF);
|
||||
NetConfig.instance().setLoggable(DebugConfig.isDebug());
|
||||
}
|
||||
}
|
||||
|
||||
private void startCatchLog(RemoteLogPushContent content) {
|
||||
catchingList.add(content.getPkgName());
|
||||
|
||||
long delay = content.getDuration() * 60 * 1000;
|
||||
handler.removeMessages(MSG_TRY_CLOSE_LOG);
|
||||
if (delay <= 0) {
|
||||
// 如果push 下来的delay小于等于0,那就给个默认最大值一小时
|
||||
delay = 60 * 60 * 1000L;
|
||||
}
|
||||
handler.sendEmptyMessageDelayed(MSG_TRY_CLOSE_LOG, delay);
|
||||
openLoggerLevel();
|
||||
sendCtrlBroadcast(content);
|
||||
}
|
||||
|
||||
private void stopCatchLog(RemoteLogPushContent content) {
|
||||
catchingList.remove(content.getPkgName());
|
||||
if (catchingList.isEmpty()) {
|
||||
handler.removeMessages(MSG_TRY_CLOSE_LOG);
|
||||
}
|
||||
sendCtrlBroadcast(content);
|
||||
closeLoggerLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLogDebugDialog() {
|
||||
if (logDebugDialog == null) {
|
||||
logDebugDialog = new LogDebugDialog(ContextHolderUtil.getContext());
|
||||
logDebugDialog.setDialogListener(this);
|
||||
}
|
||||
if (logDebugDialog.isShowing()) {
|
||||
return;
|
||||
}
|
||||
logDebugDialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners android:radius="20dp" />
|
||||
<gradient
|
||||
android:angle="-45"
|
||||
android:startColor="#3F4057"
|
||||
android:endColor="#2A2B38" />
|
||||
<padding
|
||||
android:left="20dp"
|
||||
android:right="20dp"
|
||||
android:top="20dp"
|
||||
android:bottom="20dp" />
|
||||
</shape>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<corners android:radius="16dp" />
|
||||
<gradient android:angle="135" android:endColor="#CC0033" android:startColor="#FF3366" />
|
||||
<padding android:right="20dp" android:left="20dp" android:top="10dp" android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<corners android:radius="16dp" />
|
||||
<gradient android:angle="135" android:endColor="#FF3333" android:startColor="#FF3366" />
|
||||
<padding android:right="20dp" android:left="20dp" android:top="10dp" android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="true">
|
||||
<shape android:shape="rectangle">
|
||||
<gradient android:angle="135" android:endColor="#ff113361" android:startColor="#ff124B98" android:type="linear" />
|
||||
<corners android:radius="16dp" />
|
||||
<padding android:right="20dp" android:left="20dp" android:top="10dp" android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<gradient android:angle="135" android:endColor="#ff1e57a4" android:startColor="#ff1f7eff" android:type="linear" />
|
||||
<corners android:radius="16dp" />
|
||||
<padding android:right="20dp" android:left="20dp" android:top="10dp" android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<corners android:radius="16dp" />
|
||||
<gradient android:angle="135" android:endColor="#1C1E28" android:startColor="#242737" />
|
||||
<padding android:right="20dp" android:left="20dp" android:top="10dp" android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<corners android:radius="16dp" />
|
||||
<gradient android:angle="135" android:endColor="#48495E" android:startColor="#616381" />
|
||||
<padding android:right="20dp" android:left="20dp" android:top="10dp" android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
@@ -1,76 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/log_debug_dialog_bg">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/tvLogDebugTitle"
|
||||
android:text="日志抓取工具"
|
||||
android:textSize="28sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:textColor="#fff" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/btnStart"
|
||||
android:background="@drawable/log_debug_start_btn_bg"
|
||||
android:text="开始抓取"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvLogDebugTitle"
|
||||
app:layout_constraintRight_toLeftOf="@+id/btnStop"
|
||||
android:layout_marginTop="20dp"
|
||||
android:textColor="#fff" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/btnStop"
|
||||
android:background="@drawable/log_debug_stop_btn_bg"
|
||||
android:text="结束抓取"
|
||||
app:layout_constraintTop_toTopOf="@id/btnStart"
|
||||
app:layout_constraintLeft_toRightOf="@id/btnStart"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:textSize="20sp"
|
||||
android:textColor="#fff" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/btnForceClearNotice"
|
||||
android:background="@drawable/log_debug_stop_btn_bg"
|
||||
android:text="关闭日志抓取提示"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/btnStart"
|
||||
android:layout_marginTop="20dp"
|
||||
android:textSize="20sp"
|
||||
android:textColor="#fff" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/btnRetryFlow"
|
||||
android:background="@drawable/log_debug_retry_btn_bg"
|
||||
android:text="若有上传失败,点此重试"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/btnForceClearNotice"
|
||||
android:layout_marginTop="20dp"
|
||||
android:visibility="gone"
|
||||
android:textSize="20sp"
|
||||
android:textColor="#fff" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</FrameLayout>
|
||||
Reference in New Issue
Block a user