FT8CN/ft8CN/app/src/main/java/com/bg7yoz/ft8cn/GeneralVariables.java

586 wiersze
18 KiB
Java
Executable File
Czysty Wina Historia

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.bg7yoz.ft8cn;
/**
* 常用变量。关于mainContext有内存泄漏的风险以后解决。
* mainContext
*/
import android.annotation.SuppressLint;
import android.content.Context;
import androidx.lifecycle.MutableLiveData;
import com.bg7yoz.ft8cn.callsign.CallsignDatabase;
import com.bg7yoz.ft8cn.connector.ConnectMode;
import com.bg7yoz.ft8cn.database.ControlMode;
import com.bg7yoz.ft8cn.database.DatabaseOpr;
import com.bg7yoz.ft8cn.ft8transmit.QslRecordList;
import com.bg7yoz.ft8cn.log.QSLRecord;
import com.bg7yoz.ft8cn.rigs.BaseRigOperation;
import com.bg7yoz.ft8cn.timer.UtcTimer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class GeneralVariables {
private static final String TAG = "GeneralVariables";
public static String VERSION = BuildConfig.VERSION_NAME;//版本号"0.62Beta 4";
public static String BUILD_DATE = BuildConfig.apkBuildTime;//编译的时间
public static int MESSAGE_COUNT = 3000;//消息的最大缓存数量
public static boolean saveSWLMessage=false;//保存解码消息开关
public static boolean saveSWL_QSO=false;//保存解码消息消息中的QSO开关
public static MutableLiveData<Float> mutableVolumePercent = new MutableLiveData<>();
public static float volumePercent = 0.5f;//播放音频的音量,是百分比
public static int flexMaxRfPower=10;//flex电台的最大发射功率
public static int flexMaxTunePower=10;//flex电台的最大调谐功率
private Context mainContext;
public static CallsignDatabase callsignDatabase = null;
public void setMainContext(Context context) {
mainContext = context;
}
public static boolean isChina = true;//语言是不是中国
public static boolean isTraditionalChinese = true;//语言是不是繁体中文
//public static double maxDist = 0;//最远距离
//各已经通联的分区列表
public static final Map<String, String> dxccMap = new HashMap<>();
public static final Map<Integer, Integer> cqMap = new HashMap<>();
public static final Map<Integer, Integer> ituMap = new HashMap<>();
private static final Map<String, Integer> excludedCallsigns = new HashMap<>();
/**
* 添加排除的字头
*
* @param callsigns 呼号
*/
public static synchronized void addExcludedCallsigns(String callsigns) {
excludedCallsigns.clear();
String[] s = callsigns.toUpperCase().replace(" ", ",")
.replace("|", ",")
.replace("", ",").split(",");
for (int i = 0; i < s.length; i++) {
if (s[i].length() > 0) {
excludedCallsigns.put(s[i], 0);
}
}
}
/**
* 查找是否含有排除的字头
*
* @param callsign 呼号
* @return 是否
*/
public static synchronized boolean checkIsExcludeCallsign(String callsign) {
Iterator<String> iterator = excludedCallsigns.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
if (callsign.toUpperCase().indexOf(key) == 0) {
return true;
}
}
return false;
}
/**
* 获取排除呼号前缀的列表
*
* @return 列表
*/
public static synchronized String getExcludeCallsigns() {
StringBuilder calls = new StringBuilder();
Iterator<String> iterator = excludedCallsigns.keySet().iterator();
int i = 0;
while (iterator.hasNext()) {
String key = iterator.next();
if (i == 0) {
calls.append(key);
} else {
calls.append(",").append(key);
}
i++;
}
return calls.toString();
}
//通联记录列表,包括成功与不成功的
public static QslRecordList qslRecordList = new QslRecordList();
//此处有内存泄露警告但Application Context不应该会内存泄露所以注释掉
@SuppressLint("StaticFieldLeak")
private static GeneralVariables generalVariables = null;
public static GeneralVariables getInstance() {
if (generalVariables == null) {
generalVariables = new GeneralVariables();
}
return generalVariables;
}
public static Context getMainContext() {
return GeneralVariables.getInstance().mainContext;
}
public static MutableLiveData<String> mutableDebugMessage = new MutableLiveData<>();
public static int QUERY_FREQ_TIMEOUT = 2000;//轮询频率变化的时间间隔。2秒
public static int START_QUERY_FREQ_DELAY = 2000;//开始轮询频率的时间延迟
public static final int DEFAULT_LAUNCH_SUPERVISION = 10 * 60 * 1000;//发射监管默认值,10分钟
private static String myMaidenheadGrid = "";
public static MutableLiveData<String> mutableMyMaidenheadGrid = new MutableLiveData<>();
public static int connectMode = ConnectMode.USB_CABLE;//连接方式USB==0,BLUE_TOOTH==1
//public static String bluetoothDeviceAddress=null;//可以用于连接的蓝牙设备地址
//用于记录呼号于网格的对应关系 todo---应当把此处列表也放到后台追踪信息里
//public static ArrayList<CallsignMaidenheadGrid> callsignMaidenheadGrids=new ArrayList<>();
public static final Map<String, String> callsignAndGrids = new ConcurrentHashMap<>();
//private static final Map<String,String> callsignAndGrids=new HashMap<>();
public static String myCallsign = "";//我的呼号
public static String toModifier = "ADFG";//呼叫的修饰符
private static float baseFrequency = 1000;//声音频率
public static MutableLiveData<Float> mutableBaseFrequency = new MutableLiveData<>();
public static boolean synFrequency = false;//同频发射
public static int transmitDelay = 500;//发射延迟时间,这个时间也是给上一个周期的解码时间
public static int pttDelay = 100;//PTT的响应时间在给电台PTT指令后一般电台会有一个响应时间此处默认是100毫秒
public static int civAddress = 0xa4;//civ地址
public static int baudRate = 19200;//波特率
public static long band = 14074000;//载波频段
public static int instructionSet = 0;//指令集0:icom1:yaesu 2 代2:yaesu 3代。
public static int bandListIndex = -1;//电台波段的索引值
public static MutableLiveData<Integer> mutableBandChange = new MutableLiveData<>();//波段索引值变化
public static int controlMode = ControlMode.VOX;
public static int modelNo = 0;
public static int launchSupervision = DEFAULT_LAUNCH_SUPERVISION;//发射监管
public static long launchSupervisionStart = UtcTimer.getSystemTime();//自动发射的起始时间
public static int noReplyLimit = 0;//呼叫无回应次数0==忽略
public static int noReplyCount = 0;//没有回应的次数
//下面4个参数是ICOM网络方式连接的参数
public static String icomIp = "255.255.255.255";
public static int icomUdpPort = 50001;
public static String icomUserName = "ic705";
public static String icomPassword = "";
public static boolean autoFollowCQ = true;//自动关注CQ
public static boolean autoCallFollow = true;//自动呼叫关注的呼号
public static ArrayList<String> QSL_Callsign_list = new ArrayList<>();//QSL成功的呼号
public static ArrayList<String> QSL_Callsign_list_other_band = new ArrayList<>();//在其它波段QSL成功的呼号
public static final ArrayList<String> followCallsign = new ArrayList<>();//关注的呼号
public static ArrayList<Ft8Message> transmitMessages = new ArrayList<>();//放在呼叫界面,关注的列表
public static void setMyMaidenheadGrid(String grid) {
myMaidenheadGrid = grid;
mutableMyMaidenheadGrid.postValue(grid);
}
public static String getMyMaidenheadGrid() {
return myMaidenheadGrid;
}
public static float getBaseFrequency() {
return baseFrequency;
}
public static void setBaseFrequency(float baseFrequency) {
mutableBaseFrequency.postValue(baseFrequency);
GeneralVariables.baseFrequency = baseFrequency;
}
@SuppressLint("DefaultLocale")
public static String getBaseFrequencyStr() {
return String.format("%.0f", baseFrequency);
}
public static String getCivAddressStr() {
return String.format("%2X", civAddress);
}
public static String getTransmitDelayStr() {
return String.valueOf(transmitDelay);
}
public static String getBandString() {
return BaseRigOperation.getFrequencyAllInfo(band);
}
/**
* 查有没有通联成功的呼号
*
* @param callsign 呼号
* @return 是否存在
*/
public static boolean checkQSLCallsign(String callsign) {
return QSL_Callsign_list.contains(callsign);
}
/**
* 查别的波段有没有通联成功的呼号
*
* @param callsign 呼号
* @return 是否存在
*/
public static boolean checkQSLCallsign_OtherBand(String callsign) {
return QSL_Callsign_list_other_band.contains(callsign);
}
/**
* 查该呼号是不是在关注的呼号列表中
*
* @param callsign 呼号
* @return 是否存在
*/
public static boolean callsignInFollow(String callsign) {
return followCallsign.contains(callsign);
}
/**
* 向通联成功的呼号列表添加
*
* @param callsign 呼号
*/
public static void addQSLCallsign(String callsign) {
if (!checkQSLCallsign(callsign)) {
QSL_Callsign_list.add(callsign);
}
}
public static String getMyMaidenhead4Grid() {
if (myMaidenheadGrid.length() > 4) {
return myMaidenheadGrid.substring(0, 4);
}
return myMaidenheadGrid;
}
/**
* 自动程序运行起始时间
*/
public static void resetLaunchSupervision() {
launchSupervisionStart = UtcTimer.getSystemTime();
}
/**
* 或取自动程序的运行时长
*
* @return 毫秒
*/
public static int launchSupervisionCount() {
return (int) (UtcTimer.getSystemTime() - launchSupervisionStart);
}
public static boolean isLaunchSupervisionTimeout() {
if (launchSupervision == 0) return false;//0是不监管
return launchSupervisionCount() > launchSupervision;
}
/**
* 从extraInfo中查消息顺序
*
* @param extraInfo 消息中的扩展内容
* @return 返回消息序号
*/
public static int checkFunOrderByExtraInfo(String extraInfo) {
if (checkFun5(extraInfo)) return 5;
if (checkFun4(extraInfo)) return 4;
if (checkFun3(extraInfo)) return 3;
if (checkFun2(extraInfo)) return 2;
if (checkFun1(extraInfo)) return 1;
return -1;
}
/**
* 检查消息的序号,如果解析不出来,就-1
*
* @param message 消息
* @return 消息序号
*/
public static int checkFunOrder(Ft8Message message) {
if (message.checkIsCQ()) return 6;
return checkFunOrderByExtraInfo(message.extraInfo);
}
//是不是网格报告
public static boolean checkFun1(String extraInfo) {
//网格报告必须是4位,或没有网格
return (extraInfo.trim().matches("[A-Z][A-Z][0-9][0-9]") && !extraInfo.equals("RR73"))
|| (extraInfo.trim().length() == 0);
}
//是不是信号报告,如-10
public static boolean checkFun2(String extraInfo) {
if (extraInfo.trim().length() < 2) {
return false;
}//信号报告必须至少2位
try {
return Integer.parseInt(extraInfo.trim()) != 73;//如果是73说明是消息6不是消息2
//return true;
} catch (Exception e) {
return false;
}
}
//是不是带R的信号报告,如R-10
public static boolean checkFun3(String extraInfo) {
if (extraInfo.trim().length() < 3) {
return false;
}//带R信号报告必须至少3位
//第一位如果不是R或者第二位是R说明不是消息3
if ((extraInfo.trim().charAt(0) != 'R') || (extraInfo.trim().charAt(1) == 'R')) {
return false;
}
try {
Integer.parseInt(extraInfo.trim().substring(1));
return true;
} catch (Exception e) {
return false;
}
}
//是不是RRR或RR73值
public static boolean checkFun4(String extraInfo) {
return extraInfo.trim().equals("RR73") || extraInfo.trim().equals("RRR");
}
//是不是73值
public static boolean checkFun5(String extraInfo) {
return extraInfo.trim().equals("73");
}
/**
* 判断是不是信号报告,如果是,把值赋给 report
* @param extraInfo 消息扩展
* @return 信号报告值,没找到是-100
*/
public static int checkFun2_3(String extraInfo){
if (extraInfo.equals("73")) return -100;
if (extraInfo.matches("[R]?[+-]?[0-9]{1,2}")){
try {
return Integer.parseInt(extraInfo.replace("R",""));
} catch (Exception e) {
return -100;
}
}
return -100;
}
/**
* 判断是不是网格报告,如果是,把值赋给 report
* @param extraInfo 消息扩展
* @return 信号报告
*/
public static boolean checkFun1_6(String extraInfo){
return extraInfo.trim().matches("[A-Z][A-Z][0-9][0-9]")
&& !extraInfo.trim().equals("RR73");
}
/**
* 检查是否是通联结束RRR、RR73、73
* @param extraInfo 消息后缀
* @return 是否
*/
public static boolean checkFun4_5(String extraInfo){
return extraInfo.trim().equals("RR73")
|| extraInfo.trim().equals("RRR")
||extraInfo.trim().equals("73");
}
/**
* 从String.xml中提取字符串
*
* @param id id
* @return 字符串
*/
public static String getStringFromResource(int id) {
if (getMainContext() != null) {
return getMainContext().getString(id);
} else {
return "";
}
}
/**
* 把已经通联的DXCC分区添加到集合中
*
* @param dxccPrefix DXCC前缀
*/
public static void addDxcc(String dxccPrefix) {
dxccMap.put(dxccPrefix, dxccPrefix);
}
/**
* 查看是不是已经通联的DXCC分区
*
* @param dxccPrefix DXCC前缀
* @return 是否
*/
public static boolean getDxccByPrefix(String dxccPrefix) {
return dxccMap.containsKey(dxccPrefix);
}
/**
* 把CQ分区加到列表里
*
* @param cqZone cq分区编号
*/
public static void addCqZone(int cqZone) {
cqMap.put(cqZone, cqZone);
}
/**
* 查是否存在已经通联的CQ分区
*
* @param cq cq分区编号
* @return 是否存在
*/
public static boolean getCqZoneById(int cq) {
return cqMap.containsKey(cq);
}
/**
* 把itu分区添加到已通联的ITU列表中
*
* @param itu itu编号
*/
public static void addItuZone(int itu) {
ituMap.put(itu, itu);
}
/**
* 查Itu分区在不在已通联的列表中
*
* @param itu itu编号
* @return 是否存在
*/
public static boolean getItuZoneById(int itu) {
return ituMap.containsKey(itu);
}
//用于触发新的网格
public static MutableLiveData<String> mutableNewGrid = new MutableLiveData<>();
/**
* 把呼号与网格的对应关系添加到呼号--网格对应表,
*
* @param callsign 呼号
* @param grid 网格
*/
public static void addCallsignAndGrid(String callsign, String grid) {
if (grid.length() >= 4) {
callsignAndGrids.put(callsign, grid);
mutableNewGrid.postValue(grid);
}
}
/**
* 呼号--网格对应表。以呼号查网格
* 如果内存中没有,应当到数据库中查一下。
*
* @param callsign 呼号
* @return 是否有对应的网格
*/
public static boolean getCallsignHasGrid(String callsign) {
return callsignAndGrids.containsKey(callsign);
}
/**
* 呼号--网格对应表。以呼号查网格,条件是呼号和网格都对应的上。
* 此函数的目的是,为了更新对应表的数据库
*
* @param callsign 呼号
* @param grid 网格
* @return 是否有对应的网格
*/
public static boolean getCallsignHasGrid(String callsign, String grid) {
if (!callsignAndGrids.containsKey(callsign)) return false;//说明根本没有这个呼号
String s = callsignAndGrids.get(callsign);
if (s == null) return false;
return s.equals(grid);
}
public static String getGridByCallsign(String callsign, DatabaseOpr db) {
String s = callsign.replace("<", "").replace(">", "");
if (getCallsignHasGrid(s)) {
return callsignAndGrids.get(s);
} else {
db.getCallsignQTH(callsign);
return "";
}
}
/**
* 遍历呼号--网格对应表生成HTML
*
* @return HTML
*/
public static String getCallsignAndGridToHTML() {
StringBuilder result = new StringBuilder();
int order = 0;
for (String key : callsignAndGrids.keySet()) {
order++;
if (order % 2 == 0) {
result.append("<tr class=\"bbb\" >");
} else {
result.append("<tr>");
}
result.append("<td align=center class=\"default\" >");
result.append(key);
result.append("</td>\n");
result.append("<td align=center class=\"default\" >");
result.append(callsignAndGrids.get(key));
result.append("</tr>\n");
}
return result.toString();
}
public static synchronized void deleteArrayListMore(ArrayList<Ft8Message> list) {
if (list.size() > GeneralVariables.MESSAGE_COUNT) {
while (list.size() > GeneralVariables.MESSAGE_COUNT) {
list.remove(0);
}
}
}
/**
* 判断是否为整数
*
* @param str 传入的字符串
* @return 是整数返回true, 否则返回false
*/
public static boolean isInteger(String str) {
if (str != null && !"".equals(str.trim()))
return str.matches("^[0-9]*$");
else
return false;
}
}