kopia lustrzana https://github.com/N0BOY/FT8CN
188 wiersze
5.3 KiB
Java
188 wiersze
5.3 KiB
Java
|
package com.bg7yoz.ft8cn.x6100;
|
|||
|
|
|||
|
/**
|
|||
|
* XieguRadioFactory 当前发现的所有收音机。
|
|||
|
* RadioFactory: 实例化这个类来创建一个 Radio Factory,通过它发现在相同局域网内地协谷电台。
|
|||
|
*
|
|||
|
* 通过Upd协议,在7001端口的广播数据中获取vita协议数据,并解析电台信息。
|
|||
|
*
|
|||
|
* @author BGY70Z
|
|||
|
* @date 2023-11-29
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
import android.util.Log;
|
|||
|
|
|||
|
import com.bg7yoz.ft8cn.flex.FlexRadio;
|
|||
|
import com.bg7yoz.ft8cn.flex.RadioUdpClient;
|
|||
|
import com.bg7yoz.ft8cn.flex.VITA;
|
|||
|
|
|||
|
|
|||
|
import java.net.DatagramPacket;
|
|||
|
import java.net.DatagramSocket;
|
|||
|
import java.net.InetAddress;
|
|||
|
import java.net.SocketException;
|
|||
|
import java.util.ArrayList;
|
|||
|
import java.util.Timer;
|
|||
|
import java.util.TimerTask;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
public class XieguRadioFactory {
|
|||
|
private static final String TAG="XieguRadioFactory";
|
|||
|
private static final int XIEGU_DISCOVERY_PORT =7001;
|
|||
|
private static XieguRadioFactory instance=null;
|
|||
|
private final RadioUdpClient broadcastClient ;
|
|||
|
private OnXieguRadioEvents onXieguRadioEvents;
|
|||
|
|
|||
|
private Timer refreshTimer=null;
|
|||
|
private TimerTask refreshTask=null;
|
|||
|
|
|||
|
public ArrayList<X6100Radio> xieguRadios=new ArrayList<>();
|
|||
|
|
|||
|
/**
|
|||
|
* 获取电台列表实例
|
|||
|
* @return 电台列表实例
|
|||
|
*/
|
|||
|
public static XieguRadioFactory getInstance(){
|
|||
|
if (instance==null){
|
|||
|
instance= new XieguRadioFactory();
|
|||
|
}
|
|||
|
instance.xieguRadios.clear();
|
|||
|
return instance;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
public XieguRadioFactory() {
|
|||
|
broadcastClient = new RadioUdpClient(XIEGU_DISCOVERY_PORT);
|
|||
|
|
|||
|
|
|||
|
broadcastClient.setOnUdpEvents(new RadioUdpClient.OnUdpEvents() {
|
|||
|
@Override
|
|||
|
public void OnReceiveData(DatagramSocket socket, DatagramPacket packet, byte[] data) {
|
|||
|
VITA vita = new VITA(data);
|
|||
|
|
|||
|
if (vita.isAvailable//如果数据包有效
|
|||
|
&&vita.classId64 == VITA.XIEGU_Discovery_Class_Id
|
|||
|
&&vita.streamId==VITA.XIEGU_Discovery_Stream_Id){
|
|||
|
InetAddress address = packet.getAddress();//获取ip地址
|
|||
|
updateXieguRadioList(new String(vita.payload),address.getHostAddress());
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
try {
|
|||
|
broadcastClient.setActivated(true);
|
|||
|
} catch (SocketException e) {
|
|||
|
e.printStackTrace();
|
|||
|
Log.e(TAG, "XieguRadioFactory: "+e.getMessage());
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void startRefreshTimer(){
|
|||
|
if (refreshTimer==null) {
|
|||
|
refreshTask=new TimerTask() {
|
|||
|
@Override
|
|||
|
public void run() {
|
|||
|
Log.e(TAG, "run: 检查离线" );
|
|||
|
checkOffLineRadios();
|
|||
|
}
|
|||
|
};
|
|||
|
refreshTimer=new Timer();
|
|||
|
refreshTimer.schedule(refreshTask, 1000, 1000);//检查电台列表中的电台是否在线(每一秒)
|
|||
|
}
|
|||
|
}
|
|||
|
public void cancelRefreshTimer(){
|
|||
|
if (refreshTimer!=null){
|
|||
|
refreshTimer.cancel();
|
|||
|
refreshTimer=null;
|
|||
|
refreshTask.cancel();
|
|||
|
refreshTask=null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 从数据中查找电台的MAC地址
|
|||
|
* @param s 数据
|
|||
|
* @return mac地址
|
|||
|
*/
|
|||
|
private String getMacAddress(String s){
|
|||
|
String[] strings=s.split(" ");
|
|||
|
for (int i = 0; i <strings.length ; i++) {
|
|||
|
if (strings[i].toLowerCase().startsWith("mac")){
|
|||
|
return strings[i].substring("mac".length()+1);
|
|||
|
}
|
|||
|
}
|
|||
|
return "";
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 在电台列表中查找有没有指定MAC的电台
|
|||
|
* @param mac MAC地址
|
|||
|
* @return 电台实例
|
|||
|
*/
|
|||
|
public X6100Radio checkXieguRadioByMac(String mac){
|
|||
|
for (X6100Radio radio:xieguRadios) {
|
|||
|
if (radio.isEqual(mac)){
|
|||
|
return radio;
|
|||
|
}
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
private synchronized void updateXieguRadioList(String s,String ip){
|
|||
|
String mac = getMacAddress(s);
|
|||
|
if (mac.equals("")) {return;}
|
|||
|
X6100Radio radio=checkXieguRadioByMac(mac);
|
|||
|
if (radio!=null){
|
|||
|
radio.updateLastSeen();
|
|||
|
}else {
|
|||
|
radio=new X6100Radio(s,ip);
|
|||
|
if (onXieguRadioEvents!=null){
|
|||
|
onXieguRadioEvents.onXieguRadioAdded(radio);
|
|||
|
}
|
|||
|
xieguRadios.add(radio);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 检查电台是不是离线,如果离线,触发离线事件
|
|||
|
*/
|
|||
|
private void checkOffLineRadios(){
|
|||
|
for (X6100Radio radio:xieguRadios) {
|
|||
|
if (radio.isInvalidNow()){
|
|||
|
if (onXieguRadioEvents!=null){
|
|||
|
onXieguRadioEvents.onXieguRadioInvalid(radio);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//***********Getter****************
|
|||
|
public RadioUdpClient getBroadcastClient() {
|
|||
|
return broadcastClient;
|
|||
|
}
|
|||
|
|
|||
|
public OnXieguRadioEvents getOnFlexRadioEvents() {
|
|||
|
return onXieguRadioEvents;
|
|||
|
}
|
|||
|
|
|||
|
public void setOnXieguRadioEvents(OnXieguRadioEvents onXieguRadioEvents) {
|
|||
|
this.onXieguRadioEvents = onXieguRadioEvents;
|
|||
|
}
|
|||
|
//*********************************
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* 电台列表变化的接口
|
|||
|
*/
|
|||
|
public static interface OnXieguRadioEvents{
|
|||
|
void onXieguRadioAdded(X6100Radio flexRadio);
|
|||
|
void onXieguRadioInvalid(X6100Radio flexRadio);
|
|||
|
}
|
|||
|
|
|||
|
}
|