[chang]调试程序修改
This commit is contained in:
1
app_ipc_monitoring/mogo-adas-connect-status/.gitignore
vendored
Normal file
1
app_ipc_monitoring/mogo-adas-connect-status/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
2
app_ipc_monitoring/mogo-adas-connect-status/README.md
Normal file
2
app_ipc_monitoring/mogo-adas-connect-status/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
#### 说明
|
||||
# ADAS 连接状态 LIB
|
||||
106
app_ipc_monitoring/mogo-adas-connect-status/build.gradle
Normal file
106
app_ipc_monitoring/mogo-adas-connect-status/build.gradle
Normal file
@@ -0,0 +1,106 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'maven'
|
||||
}
|
||||
//ext {
|
||||
// //自动驾驶产品版本号
|
||||
// AP_VERSION = "2.6.0"
|
||||
//}
|
||||
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")
|
||||
//
|
||||
// buildConfigField "String", "AP_VERSION", "\"${AP_VERSION}\""
|
||||
versionCode rootProject.versionCode as int
|
||||
versionName rootProject.versionName
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles 'consumer-rules.pro'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
jniLibs.srcDirs = ['libs']
|
||||
// java {
|
||||
// srcDir 'src/main/java'
|
||||
// }
|
||||
//
|
||||
// proto {
|
||||
// srcDir 'src/main/proto'
|
||||
// include '**/*.proto'
|
||||
// }
|
||||
}
|
||||
}
|
||||
//
|
||||
// protobuf {
|
||||
// protoc {
|
||||
// artifact = 'com.google.protobuf:protoc:3.6.1'
|
||||
// }
|
||||
//
|
||||
// generateProtoTasks {
|
||||
// all().each { task ->
|
||||
// task.builtins {
|
||||
// remove java
|
||||
// }
|
||||
// task.builtins {
|
||||
// java {}
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation project(':libraries:mogo-adas')
|
||||
implementation rootProject.ext.dependencies.androidxrecyclerview
|
||||
}
|
||||
|
||||
task androidSourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
}
|
||||
//配置需要上传到maven仓库的文件
|
||||
artifacts {
|
||||
archives androidSourcesJar
|
||||
}
|
||||
|
||||
uploadArchives {
|
||||
repositories.mavenDeployer {
|
||||
repository(url: RELEASE_REPOSITORY_URL) {
|
||||
authentication(userName: USERNAME, password: PASSWORD)
|
||||
}
|
||||
snapshotRepository(url: SNAPSHOT_REPOSITORY_URL) {
|
||||
authentication(userName: USERNAME, password: PASSWORD)
|
||||
}
|
||||
pom.groupId = ADAS_LIB_GROUP
|
||||
pom.artifactId = ADAS_LIB_POM_ARTIFACT_ID
|
||||
pom.version = versionName + ADAS_LIB_CHILD_VERSION
|
||||
pom.whenConfigured { pom ->
|
||||
pom.dependencies.forEach { dep ->
|
||||
if (dep.getVersion() == "unspecified") {
|
||||
println("--修改pom.xml中的dependies模块--->>" + dep.getArtifactId())
|
||||
if (dep.getArtifactId() == ADAS_DATA_LIB_POM_ARTIFACT_ID) {
|
||||
dep.setGroupId(ADAS_DATA_LIB_GROUP)
|
||||
dep.setVersion(versionName + ADAS_DATA_LIB_CHILD_VERSION)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
GROUP=com.mogo.adas
|
||||
POM_ARTIFACT_ID=mogo-adas
|
||||
VERSION_CODE=1
|
||||
26
app_ipc_monitoring/mogo-adas-connect-status/proguard-rules.pro
vendored
Normal file
26
app_ipc_monitoring/mogo-adas-connect-status/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# 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
|
||||
|
||||
#-----MogoMap-----
|
||||
-keep class com.mogo.map.MogoNavi{
|
||||
private <init>();
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.zhidao.support.adas.connect.status" >
|
||||
</manifest>
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.zhidao.support.adas.high;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.zhidao.support.adas.high.common.ConnectStatusTask;
|
||||
import com.zhidao.support.adas.high.widget.ConnectStatusFloatWindow;
|
||||
|
||||
/**
|
||||
* @ProjectName: lib-adas-fpga
|
||||
* @Package: com.zhidao.lib.adas.high
|
||||
* @ClassName: AdasManager
|
||||
* @Description: java类作用描述
|
||||
* @Author: fenghl
|
||||
* @CreateDate: 2020/2/7 13:13
|
||||
* @UpdateUser: 更新者:
|
||||
* @UpdateDate: 2020/2/7 13:13
|
||||
* @UpdateRemark: 更新说明:
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class AdasConnectStatusManager {
|
||||
private static volatile AdasConnectStatusManager ourInstance;
|
||||
|
||||
private ConnectStatusFloatWindow floatWindow;
|
||||
|
||||
public static AdasConnectStatusManager getInstance() {
|
||||
if (ourInstance == null) {
|
||||
synchronized (AdasConnectStatusManager.class) {
|
||||
if (ourInstance == null) {
|
||||
ourInstance = new AdasConnectStatusManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ourInstance;
|
||||
}
|
||||
|
||||
private AdasConnectStatusManager() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 展示连接历史
|
||||
*
|
||||
* @param activity
|
||||
*/
|
||||
public void showConnectStatusFloatWindow(Activity activity) {
|
||||
if (floatWindow == null) {
|
||||
floatWindow = new ConnectStatusFloatWindow(activity, ConnectStatusTask.getInstance().getList(), new ConnectStatusFloatWindow.OnConnectStatusFloatWindowListener() {
|
||||
@Override
|
||||
public void onClose() {
|
||||
closeConnectStatusFloatWindow();
|
||||
}
|
||||
});
|
||||
floatWindow.showFloatWindow();
|
||||
} else {
|
||||
closeConnectStatusFloatWindow();
|
||||
}
|
||||
}
|
||||
|
||||
private void closeConnectStatusFloatWindow() {
|
||||
floatWindow.hideFloatWindow();
|
||||
floatWindow = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.zhidao.support.adas.high.bean;
|
||||
|
||||
import androidx.annotation.ColorRes;
|
||||
|
||||
public class IPCConnectState {
|
||||
public final String status;
|
||||
@ColorRes
|
||||
public final int color;
|
||||
|
||||
public IPCConnectState(String status, @ColorRes int color) {
|
||||
this.status = status;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,382 @@
|
||||
package com.zhidao.support.adas.high.common;
|
||||
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.zhidao.support.adas.high.bean.IPCConnectState;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* 连接状态存储任务
|
||||
*/
|
||||
public class ConnectStatusTask {
|
||||
private static final String TAG = ConnectStatusTask.class.getSimpleName();
|
||||
public static final String ROOT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "mogo" + File.separator + "adas" + File.separator;//程序外部存储跟目录
|
||||
private static final String LOG_FILE_NAME = "ipc_connect_status.log";//文件名称
|
||||
private volatile static ConnectStatusTask INSTANCE;
|
||||
private static final int MAX_LINES = 1000;//最大存储行数
|
||||
private static final int DEL_LINES = 500;//超过最大存储行数删除的行数
|
||||
private static final int EVERY_TIME_READ_LINES = 200;//每次读取最大行数
|
||||
private LinkedBlockingQueue<String> queue;
|
||||
private BufferedWriter buff = null;
|
||||
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault());
|
||||
private File file;
|
||||
//是否写入本地
|
||||
private final AtomicBoolean isSave = new AtomicBoolean(false);
|
||||
private Future future;
|
||||
private final AtomicBoolean isInitRead = new AtomicBoolean(false);//是否已经读取过本地文件
|
||||
private final List<OnReadListener> onReadListeners = new ArrayList<>();
|
||||
private final List<IPCConnectState> listLog = new ArrayList<>();
|
||||
|
||||
private ConnectStatusTask() {
|
||||
queue = new LinkedBlockingQueue<>();
|
||||
init(false);
|
||||
ThreadPoolManager.getsInstance().submit(new ReadThread());
|
||||
}
|
||||
|
||||
public static ConnectStatusTask getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (ConnectStatusTask.class) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new ConnectStatusTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public List<IPCConnectState> getList() {
|
||||
return listLog;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
init(true);
|
||||
listLog.clear();
|
||||
if (onReadListeners.size() != 0) {
|
||||
for (int i = 0; i < onReadListeners.size(); i++) {
|
||||
onReadListeners.get(i).onRefresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setIsLogSwitch(boolean isLogSwitch) {
|
||||
this.isLogSwitch = isLogSwitch;
|
||||
}
|
||||
|
||||
public boolean isLogSwitch() {
|
||||
return isLogSwitch;
|
||||
}
|
||||
|
||||
|
||||
public boolean isSdcardUse() {
|
||||
boolean bl = false;
|
||||
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
||||
bl = true;
|
||||
}
|
||||
return bl;
|
||||
}
|
||||
|
||||
private void init(boolean isClear) {
|
||||
if (isSdcardUse()) {
|
||||
try {
|
||||
file = new File(ROOT_PATH + LOG_FILE_NAME);
|
||||
if (isClear && file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
if (!file.exists()) {
|
||||
if (!file.getParentFile().exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
file.createNewFile();
|
||||
}
|
||||
FileWriter fw = new FileWriter(file, true);
|
||||
buff = new BufferedWriter(fw);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
start();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (future == null) {
|
||||
future = ThreadPoolManager.getsInstance().submit(new WriteThread());
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
queue.clear();
|
||||
if (future != null && !future.isCancelled()) {
|
||||
future.cancel(true);
|
||||
}
|
||||
future = null;
|
||||
closeBufferedWriter();
|
||||
}
|
||||
|
||||
private void closeBufferedWriter() {
|
||||
if (buff != null) {
|
||||
try {
|
||||
buff.flush();
|
||||
buff.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
buff = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void save(String status) {
|
||||
if (isLogSwitch) {
|
||||
String time = sdf.format(new Date(System.currentTimeMillis()));
|
||||
queue.add(time + "##" + status);
|
||||
}
|
||||
}
|
||||
|
||||
private int getStatusColor(String connectStatus) {
|
||||
if (connectStatus.contains("已连接")) {
|
||||
return R.color.connect_status_connected;
|
||||
} else if (connectStatus.contains("连接中") || connectStatus.contains("重连中")) {
|
||||
return R.color.connect_status_connecting;
|
||||
} else if (connectStatus.contains("正在搜索IP")) {
|
||||
return R.color.connect_status_search_address;
|
||||
} else if (connectStatus.contains("地址不可用或不合法")) {
|
||||
return R.color.connect_status_disconnecting;
|
||||
} else {
|
||||
return R.color.connect_status_disconnected;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private synchronized void addList(String status) {
|
||||
listLog.add(0, onParse(status));
|
||||
if (onReadListeners.size() != 0) {
|
||||
for (OnReadListener listener : onReadListeners) {
|
||||
listener.onRefresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IPCConnectState onParse(String status) {
|
||||
status = status.replace("##", "\n");
|
||||
return new IPCConnectState(status, getStatusColor(status));
|
||||
}
|
||||
|
||||
//写入
|
||||
public class WriteThread implements Runnable {
|
||||
int lineNum = -1;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// L.i(TAG, "是否是主线程=" + Utils.isMainThread());
|
||||
if (lineNum == -1) {
|
||||
lineNum = lineNumber();
|
||||
}
|
||||
CupidLogUtils.i(TAG, "初始化获得的行数=" + lineNum);
|
||||
synchronized (this) {
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
try {
|
||||
String data = queue.take();
|
||||
data = data == null ? "主动断开连接" : data;
|
||||
// addList(data, true);
|
||||
// L.i(TAG, "写入Log---" + data);
|
||||
if (buff != null && !TextUtils.isEmpty(data)) {
|
||||
buff.write(data);
|
||||
buff.newLine();
|
||||
buff.flush();
|
||||
lineNum++;
|
||||
if (lineNum == MAX_LINES + 1 + DEL_LINES) {
|
||||
List<String> delLines = readAndRemoveFirstLines();
|
||||
for (String str : delLines) {
|
||||
CupidLogUtils.i(TAG, "被删除的数据=" + str);
|
||||
}
|
||||
lineNum = lineNum - DEL_LINES;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<String> readAndRemoveFirstLines() {
|
||||
List<String> strList = new ArrayList<>();
|
||||
RandomAccessFile raf = null;
|
||||
try {
|
||||
raf = new RandomAccessFile(file, "rw");
|
||||
//Initial write position
|
||||
long writePosition = raf.getFilePointer();
|
||||
for (int i = 0; i < DEL_LINES; i++) {
|
||||
String line = raf.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
strList.add(new String(line.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
|
||||
}
|
||||
// Shift the next lines upwards.
|
||||
long readPosition = raf.getFilePointer();
|
||||
|
||||
byte[] buff = new byte[1024];
|
||||
int n;
|
||||
while (-1 != (n = raf.read(buff))) {
|
||||
raf.seek(writePosition);
|
||||
raf.write(buff, 0, n);
|
||||
readPosition += n;
|
||||
writePosition += n;
|
||||
raf.seek(readPosition);
|
||||
}
|
||||
raf.setLength(writePosition);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (raf != null) {
|
||||
raf.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return strList;
|
||||
}
|
||||
|
||||
|
||||
//获取文件总行数
|
||||
private int lineNumber() {
|
||||
int lineNumber = 0;
|
||||
if (file != null)
|
||||
try {
|
||||
LineNumberReader lineNumberReader = new LineNumberReader(new FileReader(file));
|
||||
lineNumberReader.skip(Long.MAX_VALUE);
|
||||
//注意加1,实际上是读取换行符,所以需要+1
|
||||
lineNumber = lineNumberReader.getLineNumber() + 1;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
|
||||
//读取日志
|
||||
public void registerReadListener(OnReadListener onReadListener) {
|
||||
if (onReadListener != null) {
|
||||
if (!onReadListeners.contains(onReadListener)) {
|
||||
onReadListeners.add(onReadListener);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void unRegisterReadListener(OnReadListener onReadListener) {
|
||||
if (onReadListener != null)
|
||||
onReadListeners.remove(onReadListener);
|
||||
}
|
||||
|
||||
|
||||
public interface OnReadListener {
|
||||
void onRefresh();
|
||||
}
|
||||
|
||||
//读取
|
||||
public class ReadThread implements Runnable {
|
||||
RandomAccessFile rf = null;
|
||||
long len;
|
||||
long start;
|
||||
long nextend;
|
||||
long readLine = 0;
|
||||
boolean isRead = true;
|
||||
int lineNum = -1;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// L.i(TAG, "是否是主线程=" + Utils.isMainThread());
|
||||
if (lineNum == -1) {
|
||||
lineNum = lineNumber();
|
||||
}
|
||||
synchronized (this) {
|
||||
try {
|
||||
if (rf == null && file != null) {
|
||||
rf = new RandomAccessFile(file, "r");
|
||||
len = rf.length();
|
||||
start = rf.getFilePointer();
|
||||
nextend = start + len - 1;
|
||||
rf.seek(nextend);
|
||||
}
|
||||
// L.i(TAG, "len=" + len);
|
||||
// L.i(TAG, "start=" + start);
|
||||
// L.i(TAG, "nextend=" + nextend);
|
||||
String line;
|
||||
int c = -1;
|
||||
while (isRead && nextend > start) {
|
||||
c = rf.read();
|
||||
if (c == '\n' || c == '\r') {
|
||||
line = rf.readLine();
|
||||
if (!TextUtils.isEmpty(line)) {
|
||||
String log = new String(line.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
|
||||
listLog.add(onParse(log));
|
||||
}
|
||||
nextend--;
|
||||
readLine++;
|
||||
}
|
||||
nextend--;
|
||||
rf.seek(nextend);
|
||||
if (nextend == 0) {// 当文件指针退至文件开始处,输出第一行
|
||||
String log = new String(rf.readLine().getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
|
||||
listLog.add(onParse(log));
|
||||
readLine++;
|
||||
}
|
||||
if (readLine == EVERY_TIME_READ_LINES + 1) {
|
||||
isRead = false;
|
||||
}
|
||||
// L.i(TAG, "readLine=" + readLine);
|
||||
}
|
||||
Collections.reverse(listLog);
|
||||
if (onReadListeners.size() != 0) {
|
||||
for (int i = 0; i < onReadListeners.size(); i++) {
|
||||
onReadListeners.get(i).onRefresh();
|
||||
}
|
||||
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (rf != null)
|
||||
rf.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
isInitRead.set(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.zhidao.support.adas.high.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.zhidao.support.adas.high.R;
|
||||
import com.zhidao.support.adas.high.bean.IPCConnectState;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
/**
|
||||
* 连接状态
|
||||
*/
|
||||
public class ConnectStatusAdapter extends RecyclerView.Adapter<ConnectStatusAdapter.InfoViewHolder> {
|
||||
private static final String POS = "%03d. ";
|
||||
private List<IPCConnectState> mDatas;
|
||||
private Context mContext;
|
||||
|
||||
public void setData(List<IPCConnectState> mDatas) {
|
||||
this.mDatas = mDatas;
|
||||
}
|
||||
|
||||
public void refreshView() {
|
||||
// notifyItemChanged(mDatas.size()-1,0);
|
||||
notifyItemRangeChanged(0, getItemCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public InfoViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
|
||||
mContext = viewGroup.getContext();
|
||||
View remoteView = LayoutInflater.from(mContext).inflate(R.layout.item_status, viewGroup, false);
|
||||
return new InfoViewHolder(remoteView);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull InfoViewHolder viewHolder, int position) {
|
||||
if (mDatas != null) {
|
||||
IPCConnectState data = mDatas.get(position);
|
||||
viewHolder.id.setText(String.format(Locale.getDefault(), POS, getItemCount() - position));
|
||||
viewHolder.editText.setText(data.status);
|
||||
viewHolder.editText.setTextColor(mContext.getResources().getColor(data.color));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mDatas == null ? 0 : mDatas.size();
|
||||
}
|
||||
|
||||
|
||||
class InfoViewHolder extends RecyclerView.ViewHolder {
|
||||
EditText editText;
|
||||
TextView id;
|
||||
|
||||
public InfoViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
editText = itemView.findViewById(R.id.log);
|
||||
id = itemView.findViewById(R.id.id);
|
||||
itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
package com.zhidao.support.adas.high.widget;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.os.Build;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.zhidao.support.adas.high.R;
|
||||
import com.zhidao.support.adas.high.bean.IPCConnectState;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author xuxinchao
|
||||
* @description
|
||||
* @since: 2022/4/20
|
||||
*/
|
||||
public class ConnectStatusFloatWindow implements View.OnTouchListener {
|
||||
|
||||
|
||||
private final Activity mContext;
|
||||
private WindowManager.LayoutParams mWindowParams;
|
||||
private WindowManager mWindowManager;
|
||||
|
||||
private View mFloatLayout;
|
||||
private ImageView btn_drag;
|
||||
private float mInViewX;
|
||||
private float mInViewY;
|
||||
private float mDownInScreenX;
|
||||
private float mDownInScreenY;
|
||||
private float mInScreenX;
|
||||
private float mInScreenY;
|
||||
private RecyclerView rv_status;
|
||||
private ConnectStatusAdapter adapter;
|
||||
private List<IPCConnectState> list;
|
||||
private OnConnectStatusFloatWindowListener listener;
|
||||
|
||||
public interface OnConnectStatusFloatWindowListener {
|
||||
void onClose();
|
||||
}
|
||||
|
||||
public ConnectStatusFloatWindow(Activity context, List<IPCConnectState> list, OnConnectStatusFloatWindowListener listener) {
|
||||
this.mContext = context;
|
||||
this.list = list;
|
||||
this.listener = listener;
|
||||
initFloatWindow();
|
||||
}
|
||||
|
||||
public void refreshView() {
|
||||
if (adapter != null) {
|
||||
adapter.refreshView();
|
||||
}
|
||||
}
|
||||
|
||||
private void initRV() {
|
||||
//创建默认的线性LayoutManager 横向的GridLayoutManager
|
||||
MyLinearLayoutManager linearLayoutManager = new MyLinearLayoutManager(mContext);
|
||||
// linearLayoutManager.setStackFromEnd(true);//列表再底部开始展示,反转后由上面开始展示
|
||||
// linearLayoutManager.setReverseLayout(true);//列表翻转
|
||||
rv_status.setLayoutManager(linearLayoutManager);
|
||||
//如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
|
||||
rv_status.setHasFixedSize(false);
|
||||
rv_status.setNestedScrollingEnabled(false);
|
||||
adapter = new ConnectStatusAdapter();
|
||||
adapter.setHasStableIds(true);
|
||||
rv_status.setAdapter(adapter);
|
||||
adapter.setData(list);
|
||||
}
|
||||
|
||||
private void initFloatWindow() {
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
if (inflater == null)
|
||||
return;
|
||||
mFloatLayout = inflater.inflate(R.layout.layout_float, null);
|
||||
rv_status = mFloatLayout.findViewById(R.id.rv_status);
|
||||
View btn_close = mFloatLayout.findViewById(R.id.btn_close);
|
||||
View btn_help = mFloatLayout.findViewById(R.id.btn_help);
|
||||
View btn_save = mFloatLayout.findViewById(R.id.btn_save);
|
||||
btn_drag = mFloatLayout.findViewById(R.id.btn_drag);
|
||||
btn_close.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (listener != null)
|
||||
listener.onClose();
|
||||
}
|
||||
});
|
||||
btn_help.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Toast.makeText(v.getContext(), "功能提示\n1.将数连接状态写入本地;\n2.清空列表以及保存到本地的数据;\n3.拖拽;\n4.帮助;\n5.关闭此窗口;", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
btn_save.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
}
|
||||
});
|
||||
mFloatLayout.setOnTouchListener(this);
|
||||
initRV();
|
||||
mWindowParams = new WindowManager.LayoutParams();
|
||||
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
if (Build.VERSION.SDK_INT >= 26) {//8.0新特性
|
||||
mWindowParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
} else {
|
||||
mWindowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
|
||||
}
|
||||
|
||||
mWindowManager = mContext.getWindowManager();
|
||||
|
||||
mWindowParams.format = PixelFormat.RGBA_8888;
|
||||
mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||
mWindowParams.gravity = Gravity.START | Gravity.TOP;
|
||||
mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
mWindowParams.alpha = 0.82F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
return floatLayoutTouch(motionEvent);
|
||||
}
|
||||
|
||||
private boolean floatLayoutTouch(MotionEvent motionEvent) {
|
||||
switch (motionEvent.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
// 获取相对View的坐标,即以此View左上角为原点
|
||||
mInViewX = motionEvent.getX();
|
||||
mInViewY = motionEvent.getY();
|
||||
// 获取相对屏幕的坐标,即以屏幕左上角为原点
|
||||
mDownInScreenX = motionEvent.getRawX();
|
||||
mDownInScreenY = motionEvent.getRawY() - getSysBarHeight(mContext);
|
||||
mInScreenX = motionEvent.getRawX();
|
||||
mInScreenY = motionEvent.getRawY() - getSysBarHeight(mContext);
|
||||
btn_drag.setSelected(true);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
// 更新浮动窗口位置参数
|
||||
mInScreenX = motionEvent.getRawX();
|
||||
mInScreenY = motionEvent.getRawY() - getSysBarHeight(mContext);
|
||||
mWindowParams.x = (int) (mInScreenX - mInViewX);
|
||||
mWindowParams.y = (int) (mInScreenY - mInViewY);
|
||||
// 手指移动的时候更新小悬浮窗的位置
|
||||
mWindowManager.updateViewLayout(mFloatLayout, mWindowParams);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
btn_drag.setSelected(false);
|
||||
// 如果手指离开屏幕时,xDownInScreen和xInScreen相等,且yDownInScreen和yInScreen相等,则视为触发了单击事件。
|
||||
if (mDownInScreenX == mInScreenX && mDownInScreenY == mInScreenY) {
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public void showFloatWindow() {
|
||||
if (mFloatLayout.getParent() == null) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
// 默认固定位置,靠屏幕右边缘的中间
|
||||
mWindowManager.getDefaultDisplay().getMetrics(metrics);
|
||||
mWindowParams.x = metrics.widthPixels;
|
||||
mWindowParams.y = metrics.heightPixels;
|
||||
mWindowManager.addView(mFloatLayout, mWindowParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void hideFloatWindow() {
|
||||
if (mFloatLayout.getParent() != null)
|
||||
mWindowManager.removeView(mFloatLayout);
|
||||
}
|
||||
|
||||
public void setFloatLayoutAlpha(boolean alpha) {
|
||||
if (alpha)
|
||||
mFloatLayout.setAlpha((float) 0.5);
|
||||
else
|
||||
mFloatLayout.setAlpha(1);
|
||||
}
|
||||
|
||||
private int sbar = -1;
|
||||
|
||||
// 获取系统状态栏高度
|
||||
public int getSysBarHeight(Context contex) {
|
||||
if (sbar == -1) {
|
||||
Class<?> c;
|
||||
Object obj;
|
||||
Field field;
|
||||
int x;
|
||||
sbar = 0;
|
||||
try {
|
||||
c = Class.forName("com.android.internal.R$dimen");
|
||||
obj = c.newInstance();
|
||||
field = c.getField("status_bar_height");
|
||||
x = Integer.parseInt(field.get(obj).toString());
|
||||
sbar = contex.getResources().getDimensionPixelSize(x);
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
return sbar;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.zhidao.support.adas.high.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class MyLinearLayoutManager extends LinearLayoutManager {
|
||||
public MyLinearLayoutManager(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public MyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
|
||||
super(context, orientation, reverseLayout);
|
||||
}
|
||||
|
||||
public MyLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPredictiveItemAnimations() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
|
||||
//override this method and implement code as below
|
||||
try {
|
||||
super.onLayoutChildren(recycler, state);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#FA3B4577" />
|
||||
<stroke
|
||||
android:width="0.2dp"
|
||||
android:color="#AF3B4577" />
|
||||
<!-- 圆角 -->
|
||||
<corners android:radius="6dp" />
|
||||
</shape>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#3B4577"
|
||||
android:pathData="M148.86,185.78c-25.64,0 -46.44,-21.63 -46.44,-48.28s20.8,-48.28 46.44,-48.28h316.74V48.28C465.6,21.63 486.4,0 512.04,0c25.73,0 46.44,21.63 46.44,48.28v40.94h316.65c25.73,0 46.44,21.63 46.44,48.28s-20.71,48.28 -46.44,48.28H148.86zM754.79,927.44l67.8,-573.76H201.38L269.18,927.44h485.6zM875.16,257.11c13.28,0 25.92,5.99 34.74,16.32 8.92,10.33 13,24.14 11.33,37.85L841.91,981.61c-2.79,24.23 -22.57,42.39 -46.07,42.39H228.13c-23.5,0 -43.28,-18.16 -46.07,-42.39L102.73,311.29c-1.58,-13.71 2.51,-27.52 11.42,-37.85 8.73,-10.33 21.37,-16.32 34.74,-16.32h726.27z" />
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#99CCCC"
|
||||
android:pathData="M148.86,185.78c-25.64,0 -46.44,-21.63 -46.44,-48.28s20.8,-48.28 46.44,-48.28h316.74V48.28C465.6,21.63 486.4,0 512.04,0c25.73,0 46.44,21.63 46.44,48.28v40.94h316.65c25.73,0 46.44,21.63 46.44,48.28s-20.71,48.28 -46.44,48.28H148.86zM754.79,927.44l67.8,-573.76H201.38L269.18,927.44h485.6zM875.16,257.11c13.28,0 25.92,5.99 34.74,16.32 8.92,10.33 13,24.14 11.33,37.85L841.91,981.61c-2.79,24.23 -22.57,42.39 -46.07,42.39H228.13c-23.5,0 -43.28,-18.16 -46.07,-42.39L102.73,311.29c-1.58,-13.71 2.51,-27.52 11.42,-37.85 8.73,-10.33 21.37,-16.32 34.74,-16.32h726.27z" />
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M584.41,512l362.04,362.04c20,20 20,52.42 0,72.41 -19.99,19.99 -52.41,19.99 -72.4,0L512,584.41l-362.04,362.04c-20,19.99 -52.42,19.99 -72.41,0 -19.99,-19.99 -19.99,-52.41 0,-72.41L439.59,512l-362.04,-362.04c-19.99,-20 -19.99,-52.42 0,-72.41 19.99,-19.99 52.41,-19.99 72.41,0L512,439.59l362.04,-362.04c20,-19.99 52.42,-19.99 72.41,0 19.99,19.99 19.99,52.41 0,72.41L584.41,512z"
|
||||
android:fillColor="#3B4577"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M584.41,512l362.04,362.04c20,20 20,52.42 0,72.41 -19.99,19.99 -52.41,19.99 -72.4,0L512,584.41l-362.04,362.04c-20,19.99 -52.42,19.99 -72.41,0 -19.99,-19.99 -19.99,-52.41 0,-72.41L439.59,512l-362.04,-362.04c-19.99,-20 -19.99,-52.42 0,-72.41 19.99,-19.99 52.41,-19.99 72.41,0L512,439.59l362.04,-362.04c20,-19.99 52.42,-19.99 72.41,0 19.99,19.99 19.99,52.41 0,72.41L584.41,512z"
|
||||
android:fillColor="#99CCCC"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M1020.93,527.02a39.41,39.41 0,0 0,3.06 -15.05c0,-5.25 -1.1,-10.34 -3.06,-15.12a38.45,38.45 0,0 0,-8.46 -12.62l-162.54,-162.55c-15.28,-15.28 -40.04,-15.28 -55.41,0 -15.28,15.36 -15.28,40.13 0,55.41l95.69,95.69h-339.03V133.67l95.69,95.69a39.04,39.04 0,0 0,27.67 11.44c10.03,0 20.06,-3.84 27.74,-11.44 15.28,-15.36 15.28,-40.12 0,-55.41L539.66,11.4c-1.8,-1.88 -4.08,-2.74 -6.19,-4.15 -2.11,-1.41 -3.99,-3.22 -6.43,-4.23a39.46,39.46 0,0 0,-30.17 0c-2.43,1.02 -4.23,2.82 -6.43,4.23 -2.04,1.41 -4.31,2.27 -6.2,4.15L321.71,173.95c-15.28,15.28 -15.28,40.05 0,55.41a39.21,39.21 0,0 0,55.41 0l95.69,-95.69V472.79H133.78l95.61,-95.69c15.36,-15.28 15.36,-40.05 0,-55.41 -15.28,-15.28 -40.05,-15.28 -55.41,0L11.53,484.23A37.27,37.27 0,0 0,3.05 496.85,38.37 38.37,0 0,0 0,511.98a37.99,37.99 0,0 0,3.06 15.05,37.59 37.59,0 0,0 8.46,12.7l162.46,162.47a39.03,39.03 0,0 0,27.74 11.44c10.04,0 20.06,-3.76 27.66,-11.44 15.36,-15.28 15.36,-40.12 0,-55.41L133.78,551.16h339.03v339.05l-95.69,-95.62a39.07,39.07 0,0 0,-55.41 0c-15.28,15.28 -15.28,40.05 0,55.41l162.46,162.47a39.44,39.44 0,0 0,12.85 8.46A37.89,37.89 0,0 0,511.99 1024c5.09,0 10.19,-1.02 14.89,-3.06a38.63,38.63 0,0 0,12.85 -8.46l162.54,-162.47c15.28,-15.36 15.28,-40.13 0,-55.41 -15.36,-15.36 -40.12,-15.36 -55.41,0l-95.69,95.62v-339.05h339.03l-95.69,95.62c-15.28,15.28 -15.28,40.12 0,55.41a39.03,39.03 0,0 0,27.74 11.44c10.04,0 20.06,-3.76 27.66,-11.44l162.54,-162.47a38.77,38.77 0,0 0,8.46 -12.7"
|
||||
android:fillColor="#3B4577"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M1020.93,527.02a39.41,39.41 0,0 0,3.06 -15.05c0,-5.25 -1.1,-10.34 -3.06,-15.12a38.45,38.45 0,0 0,-8.46 -12.62l-162.54,-162.55c-15.28,-15.28 -40.04,-15.28 -55.41,0 -15.28,15.36 -15.28,40.13 0,55.41l95.69,95.69h-339.03V133.67l95.69,95.69a39.04,39.04 0,0 0,27.67 11.44c10.03,0 20.06,-3.84 27.74,-11.44 15.28,-15.36 15.28,-40.12 0,-55.41L539.66,11.4c-1.8,-1.88 -4.08,-2.74 -6.19,-4.15 -2.11,-1.41 -3.99,-3.22 -6.43,-4.23a39.46,39.46 0,0 0,-30.17 0c-2.43,1.02 -4.23,2.82 -6.43,4.23 -2.04,1.41 -4.31,2.27 -6.2,4.15L321.71,173.95c-15.28,15.28 -15.28,40.05 0,55.41a39.21,39.21 0,0 0,55.41 0l95.69,-95.69V472.79H133.78l95.61,-95.69c15.36,-15.28 15.36,-40.05 0,-55.41 -15.28,-15.28 -40.05,-15.28 -55.41,0L11.53,484.23A37.27,37.27 0,0 0,3.05 496.85,38.37 38.37,0 0,0 0,511.98a37.99,37.99 0,0 0,3.06 15.05,37.59 37.59,0 0,0 8.46,12.7l162.46,162.47a39.03,39.03 0,0 0,27.74 11.44c10.04,0 20.06,-3.76 27.66,-11.44 15.36,-15.28 15.36,-40.12 0,-55.41L133.78,551.16h339.03v339.05l-95.69,-95.62a39.07,39.07 0,0 0,-55.41 0c-15.28,15.28 -15.28,40.05 0,55.41l162.46,162.47a39.44,39.44 0,0 0,12.85 8.46A37.89,37.89 0,0 0,511.99 1024c5.09,0 10.19,-1.02 14.89,-3.06a38.63,38.63 0,0 0,12.85 -8.46l162.54,-162.47c15.28,-15.36 15.28,-40.13 0,-55.41 -15.36,-15.36 -40.12,-15.36 -55.41,0l-95.69,95.62v-339.05h339.03l-95.69,95.62c-15.28,15.28 -15.28,40.12 0,55.41a39.03,39.03 0,0 0,27.74 11.44c10.04,0 20.06,-3.76 27.66,-11.44l162.54,-162.47a38.77,38.77 0,0 0,8.46 -12.7"
|
||||
android:fillColor="#99CCCC"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,15 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M40.96,853.95a40.96,40.96 0,0 1,-40.96 -40.96V81.92a40.96,40.96 0,0 1,40.96 -40.96h942.08a40.96,40.96 0,0 1,40.96 40.96v731.07a40.96,40.96 0,0 1,-40.96 40.96h-308.18l-132.45,146.33c-16.3,18.01 -44.6,17.96 -60.83,-0.1l-131.43,-146.23H40.96zM81.92,122.88v649.15h286.48a40.96,40.96 0,0 1,30.46 13.58l113.29,126.03 114.17,-126.14a40.96,40.96 0,0 1,30.37 -13.47H942.08V122.88H81.92z"
|
||||
android:fillColor="#3B4577"/>
|
||||
<path
|
||||
android:pathData="M470.27,261.12a40.96,40.96 0,1 1,81.92 0v212.08a40.96,40.96 0,0 1,-81.92 0V261.12z"
|
||||
android:fillColor="#3B4577"/>
|
||||
<path
|
||||
android:pathData="M564.71,627.91c0,30.04 -24.47,54.47 -54.56,54.47 -30.18,0 -54.47,-24.43 -54.47,-54.47A54.37,54.37 0,0 1,510.15 573.44c30.09,0 54.56,24.34 54.56,54.47"
|
||||
android:fillColor="#3B4577"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,15 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M40.96,853.95a40.96,40.96 0,0 1,-40.96 -40.96V81.92a40.96,40.96 0,0 1,40.96 -40.96h942.08a40.96,40.96 0,0 1,40.96 40.96v731.07a40.96,40.96 0,0 1,-40.96 40.96h-308.18l-132.45,146.33c-16.3,18.01 -44.6,17.96 -60.83,-0.1l-131.43,-146.23H40.96zM81.92,122.88v649.15h286.48a40.96,40.96 0,0 1,30.46 13.58l113.29,126.03 114.17,-126.14a40.96,40.96 0,0 1,30.37 -13.47H942.08V122.88H81.92z"
|
||||
android:fillColor="#99CCCC"/>
|
||||
<path
|
||||
android:pathData="M470.27,261.12a40.96,40.96 0,1 1,81.92 0v212.08a40.96,40.96 0,0 1,-81.92 0V261.12z"
|
||||
android:fillColor="#99CCCC"/>
|
||||
<path
|
||||
android:pathData="M564.71,627.91c0,30.04 -24.47,54.47 -54.56,54.47 -30.18,0 -54.47,-24.43 -54.47,-54.47A54.37,54.37 0,0 1,510.15 573.44c30.09,0 54.56,24.34 54.56,54.47"
|
||||
android:fillColor="#99CCCC"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M805,923.08a37.67,37.67 0,0 1,37.65 37.66,37.67 37.67,0 0,1 -37.65,37.66L58.14,998.4A37.67,37.67 0,0 1,20.48 960.74L20.48,213.88a37.67,37.67 0,0 1,37.66 -37.65,37.67 37.67,0 0,1 37.65,37.65v709.21h709.21zM246.41,772.46h671.56L917.97,100.92L246.42,100.92v671.55zM955.63,25.6A37.67,37.67 0,0 1,993.28 63.26v746.86a37.67,37.67 0,0 1,-37.66 37.65L208.76,847.77a37.67,37.67 0,0 1,-37.65 -37.65L171.11,63.26A37.67,37.67 0,0 1,208.76 25.6h746.86zM555.54,642.62l-125.39,-125.39a37.68,37.68 0,0 1,0 -53.25,37.68 37.68,0 0,1 53.24,0l61.15,61.08L544.54,272.23c0,-20.79 16.79,-37.65 37.65,-37.65a37.67,37.67 0,0 1,37.66 37.65v252.83l61.08,-61.08a37.68,37.68 0,0 1,53.24 0,37.68 37.68,0 0,1 0,53.25l-125.39,125.39a37.46,37.46 0,0 1,-26.59 11,37.5 37.5,0 0,1 -26.66,-10.99z"
|
||||
android:fillColor="#3B4577"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M805,923.08a37.67,37.67 0,0 1,37.65 37.66,37.67 37.67,0 0,1 -37.65,37.66L58.14,998.4A37.67,37.67 0,0 1,20.48 960.74L20.48,213.88a37.67,37.67 0,0 1,37.66 -37.65,37.67 37.67,0 0,1 37.65,37.65v709.21h709.21zM246.41,772.46h671.56L917.97,100.92L246.42,100.92v671.55zM955.63,25.6A37.67,37.67 0,0 1,993.28 63.26v746.86a37.67,37.67 0,0 1,-37.66 37.65L208.76,847.77a37.67,37.67 0,0 1,-37.65 -37.65L171.11,63.26A37.67,37.67 0,0 1,208.76 25.6h746.86zM555.54,642.62l-125.39,-125.39a37.68,37.68 0,0 1,0 -53.25,37.68 37.68,0 0,1 53.24,0l61.15,61.08L544.54,272.23c0,-20.79 16.79,-37.65 37.65,-37.65a37.67,37.67 0,0 1,37.66 37.65v252.83l61.08,-61.08a37.68,37.68 0,0 1,53.24 0,37.68 37.68,0 0,1 0,53.25l-125.39,125.39a37.46,37.46 0,0 1,-26.59 11,37.5 37.5,0 0,1 -26.66,-10.99z"
|
||||
android:fillColor="#99CCCC"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_clear_true" android:state_pressed="true" />
|
||||
<item android:drawable="@drawable/ic_clear_false" />
|
||||
</selector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_close_true" android:state_pressed="true" />
|
||||
<item android:drawable="@drawable/ic_close_false" />
|
||||
</selector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_drag_true" android:state_selected="true" />
|
||||
<item android:drawable="@drawable/ic_drag_false" />
|
||||
</selector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_help_true" android:state_pressed="true" />
|
||||
<item android:drawable="@drawable/ic_help_false" />
|
||||
</selector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_save_true" android:state_selected="true" />
|
||||
<item android:drawable="@drawable/ic_save_false" />
|
||||
</selector>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--测试列表Item-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/id"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#999999"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/log"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:cursorVisible="false"
|
||||
android:focusable="false"
|
||||
android:textColor="#ff0000"
|
||||
android:textSize="12sp" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="260dp"
|
||||
android:layout_height="320dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="3dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_save"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/selector_save" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_clear"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/selector_clear" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_drag"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/selector_drag" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_help"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/selector_help" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_close"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:src="@drawable/selector_close" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="2dp"
|
||||
android:background="@drawable/bg_float" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="connect_status_connected">#32CD32</color>
|
||||
<color name="connect_status_disconnected">#DC143C</color>
|
||||
<color name="connect_status_connecting">#FF00FF</color>
|
||||
<color name="connect_status_disconnecting">#DAA520</color>
|
||||
<color name="connect_status_search_address">#1E90FF</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">adas-status</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user