package com.osanwen.nettydemo;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.content.LocalBroadcastManager;
asd
import com.google.gson.Gson;
import com.osanwen.nettydemo.bean.DescribeBean;
import com.osanwen.nettydemo.bean.FunctionBeanList;
import com.osanwen.nettydemo.coap.CoAP;
import com.osanwen.nettydemo.coap.DataParser;
import com.osanwen.nettydemo.coap.DataSerializer;
import com.osanwen.nettydemo.coap.DescribeReturn;
import com.osanwen.nettydemo.coap.EmptyMessage;
import com.osanwen.nettydemo.coap.FunctionReturn;
import com.osanwen.nettydemo.coap.Hello;
import com.osanwen.nettydemo.coap.Ping;
import com.osanwen.nettydemo.coap.VariableReturn;
import com.osanwen.nettydemo.utils.Encryptor;
import com.osanwen.nettydemo.utils.LogUtil;
import com.osanwen.nettydemo.utils.RSAUtils;
import com.osanwen.nettydemo.utils.Utils;
import com.osanwen.nettydemo.utils.VideoUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import timber.log.Timber;
/**
* Created by LiuSaibao on 11/17/2016.
*/
public class NettyService extends Service implements NettyListener {
private NetworkReceiver receiver;
private static String sessionId = null;
private ScheduledExecutorService mScheduledExecutorService;
//关闭定时器
private void shutdown() {
if (mScheduledExecutorService != null) {
mScheduledExecutorService.shutdown();
mScheduledExecutorService = null;
}
counter = 1;
}
@Override
public void onCreate() {
super.onCreate();
receiver = new NetworkReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
NettyClient.getInstance().setListener(this);
connect();
return START_NOT_STICKY;
}
@Override
public void onServiceStatusConnectChanged(int statusCode) { //连接状态监听
Timber.d("connect status:%d", statusCode);
if (statusCode == NettyListener.STATUS_CONNECT_SUCCESS) {
sendBrodcast(this, UPDATE_TXT_MES, "连接成功");
LogUtil.v("loginHandler", "连接成功");
// authenticData();
} else {
WriteLogUtil.writeLogByThread("tcp connect error");
sendBrodcast(this, UPDATE_TXT_MES, "连接失败,取消心跳");
LogUtil.v("LoginHandler", "连接失败");
if(ifUseProducerAndConsumer) {
consumer.stop();
producer.stop();
}
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// sendBrodcast(this, UPDATE_TXT_MES, "重新连接");
//取消心跳
shutdown();
}
}
boolean ifUseProducerAndConsumer = true; //是否使用生产者消费模型 临时变量
//生产者消费模型 start
private final int TEMP_LEN = 1024 * 2; //缓存大小
private byte[] tempBytes = new byte[TEMP_LEN]; //缓存
private int writePos = 0; //读取的位置
private int readPos = 0; //写入的位置
private class Producer implements Runnable {
private BlockingQueue<EmptyMessage> queue;
private boolean isRunning = true;
public void stop() {
isRunning = false;
}
public Producer(BlockingQueue<EmptyMessage> q) {
this.queue = q;
}
@Override
public void run() {
//生产消息 定时检测缓存区里是否有完整的数据
while (isRunning) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//当前要处理的消息的长度
int msgLen = getTempbytesHeadLen();
//判断消息是完整的
int currentContentLen = writePos - readPos;
if (currentContentLen < 0) {
currentContentLen += TEMP_LEN;
}
//如果当前缓存的内容的长度足够
if (currentContentLen >= (msgLen + HEADLEN)) {
//解析消息并加入BlockingQueue中
byte[] contentBytes = new byte[msgLen];
// [0,10) readPos = 8 contentLen = 4;
if (((msgLen + HEADLEN) + readPos <= TEMP_LEN)) { //数据全部在tempBytes的[readPos,readPos+currentContentLen)
System.arraycopy(tempBytes, readPos + HEADLEN, contentBytes, 0, msgLen);
} else { //数据在tempBytes的[readPos,TEMP_LEN) 和 [0,(msgLen+HEADLEN)-(TEMP_LEN - readPos)) 两个区间
int tailLen = TEMP_LEN - readPos-HEADLEN; //8
int headLen = (msgLen) - tailLen; //8
System.arraycopy(tempBytes, readPos + HEADLEN, contentBytes, 0, tailLen); //复制尾部的数据
System.arraycopy(tempBytes, 0, contentBytes, tailLen, headLen); //复制头部的数据
}
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Producer-run()--contentBytes="+RSAUtils.bytesToHexString(contentBytes));
byte[] singleDecryptBytes = Encryptor.decrypt(Const.AES_KEY, Const.AES_IV_JIEMI, contentBytes);
if(singleDecryptBytes == null){
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Producer-run()--解密失败");
}
//更新解密iv
System.arraycopy(contentBytes, 0, Const.AES_IV_JIEMI, 0, AES_IV_LEN);
//转化为emptyMessage对象
EmptyMessage msg = null;
try {
msg = dataParser.parseMessage(singleDecryptBytes);
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "收到的消息-msg:" + msg.toString());
} catch (Exception e) {
e.printStackTrace();
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "COAP PARSER报错!!e=" + e.getLocalizedMessage());
LogUtil.v("LoginHandler", "COAP PARSER报错!!e=" + e.getLocalizedMessage());
}
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Producer-run()--writePos=" + writePos+"-readPos="+readPos);
// sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Producer-run()--msg=" + new Gson().toJson(msg));
if (msg != null) {
//维护readPos
readPos += msgLen + HEADLEN;
readPos %= TEMP_LEN; //维护readPos
queue.offer(msg); //插入队列 add会报错 offer不会报错 peek()取得最早插入队列的数值
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Producer-run()--readPos=" + readPos+"---queue.size="+queue.size());
}
}
}
}
}
public class Consumer implements Runnable {
private BlockingQueue<EmptyMessage> queue;
private boolean ifRunning = true;
public Consumer(BlockingQueue<EmptyMessage> q) {
this.queue = q;
}
@Override
public void run() {
try {
EmptyMessage msg;
//获取并处理消息
while (ifRunning) {
msg = queue.take(); //如果queue为空 会阻塞在这里
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Consumer-run()--处理消息--msg=" + new Gson().toJson(msg));
operateMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void stop(){
ifRunning = false;
}
}
//获取headBytes 当前要解析的数据的头长度
private int getTempbytesHeadLen() {
byte[] headBytes = new byte[HEADLEN];
System.arraycopy(tempBytes, readPos, headBytes, 0, HEADLEN);
return getLenByHexString(headBytes);
}
//生产者消费模型 end
private void sendBrodcast(Context context, String action, String mes) {
Intent intent = new Intent(action);
LogUtil.v("loginhandler", "sendBrodcast" + mes);
intent.putExtra("mes", Utils.getDataTimeString() + " " + mes);
context.sendBroadcast(intent);
}
public final static String UPDATE_TXT_MES = "COM.ACTION.UPDATE_TXT_MES";
static final int VALIDATE_LEN = 40;
static final int DEVICEID_LEN = 12;
static final int RSA_PUBLICKEY_LEN = 162;
//sessionID和签名信息
static final int SIGNATURE_LEN = 384;
public static final int SESSION_LEN = 40;
public static final int AES_KEY_LEN = 16;
public static final int AES_IV_LEN = 16;
static final int HELLO_MES_LEN = 50;
static final int PING_MES_LEN = 18;
int countMes = 0;
// boolean ifHaveConnect = true;
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public synchronized void onMessageResponse(byte[] byteBuf) {
sendBrodcast(this, UPDATE_TXT_MES, "收到的消息长度:" + byteBuf.length /*+ "---内容:" + new Gson().toJson(byteBuf)*/);
// if(byteBuf.length % 16 != 2 && (byteBuf.length != VALIDATE_LEN && byteBuf.length !=SIGNATURE_LEN && byteBuf.length !=HELLO_MES_LEN)){
// sendBrodcast(this, UPDATE_TXT_MES, "消息已忽略:" + byteBuf.length /*+ "---内容:" + new Gson().toJson(byteBuf)*/);
// return;
// }
countMes++;
LogUtil.v("LoginHandler", "收到信息数量统计=" + countMes);
switch (byteBuf.length) {
case VALIDATE_LEN: {
validate(byteBuf);
break;
}
case SIGNATURE_LEN: {
secondHand(byteBuf);
break;
}
case HELLO_MES_LEN: { //50位
anylisedHelloMes(byteBuf);
break;
}
default: {
anylisedOtherMes(byteBuf);
}
}
}
int counter = 1;
final int HEADLEN = 2; //头长度 0010
//解析其他的消息
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private synchronized void anylisedOtherMes(byte[] byteBuf) {
if (ifUseProducerAndConsumer) {
int contentLen = byteBuf.length;
//[0,10)
//写入缓存tempBytes 判断writePos 如果(writePos+contentLen)小于TEMP_LEN 则直接拼接到tempBytes尾部
if (writePos + contentLen <= TEMP_LEN) {
System.arraycopy(byteBuf, 0, tempBytes, writePos, contentLen);
} else { //判断writePos 如果(writePos+contentLen)大于TEMP_LEN 将超出的数据放到数组头部去
int tailLen = TEMP_LEN - writePos;
int headLen = contentLen - tailLen;
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "anylisedOtherMes--tailLen=" + tailLen+" headLen="+headLen);
System.arraycopy(byteBuf, 0, tempBytes, writePos, tailLen); //将尾部填满
System.arraycopy(byteBuf, tailLen, tempBytes, 0, headLen); //将超出的数据放到数组头部去
}
//维护writePos
writePos += contentLen;
writePos %= TEMP_LEN;
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "anylisedOtherMes--writePos=" + writePos);
return;
}
LogUtil.v("LoginHandler", "收到的消息数据-=" + RSAUtils.bytesToHexString(byteBuf));
int lenghtAll = byteBuf.length; //总数据长度
int hasAnalyseLen = 0; //已经解析的数据长度
LogUtil.v("LoginHandler", "总数据长度=" + lenghtAll);
while (hasAnalyseLen < lenghtAll) {
LogUtil.v("LoginHandler", "循环处理消息hasAnalyseLen=" + hasAnalyseLen);
byte lenBytes[] = new byte[HEADLEN];
System.arraycopy(byteBuf, hasAnalyseLen, lenBytes, 0, HEADLEN);
int singleLength = getLenByHexString(lenBytes); //单个消息长度
LogUtil.v("LoginHandler", "单个数据长度=" + singleLength);
singleLength = Math.min(singleLength, lenghtAll - HEADLEN);
byte singleBytes[] = new byte[singleLength]; //单个消息
System.arraycopy(byteBuf, hasAnalyseLen + HEADLEN, singleBytes, 0, singleLength); //复制到单个数据
LogUtil.v("LoginHandler", "解密前的数据singleBytes=" + RSAUtils.bytesToHexString(singleBytes));
byte[] singleDecryptBytes = Encryptor.decrypt(Const.AES_KEY, Const.AES_IV_JIEMI, singleBytes);
LogUtil.v("LoginHandler", "解密长度=" + singleLength + "解密结果==" + RSAUtils.bytesToHexString(singleDecryptBytes));
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "解密结果==" + RSAUtils.bytesToHexString(singleDecryptBytes));
// //更新解密iv
System.arraycopy(singleBytes, 0, Const.AES_IV_JIEMI, 0, AES_IV_LEN);
if (singleDecryptBytes == null) {
LogUtil.v("LoginHandler", "解密失败!");
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "解密失败:hasAnalyseLen=" + hasAnalyseLen);
}
EmptyMessage msg = null;
try {
msg = dataParser.parseMessage(singleDecryptBytes);
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "收到的消息-msg:" + msg.toString());
} catch (Exception e) {
e.printStackTrace();
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "COAP PARSER报错!!e=" + e.getLocalizedMessage());
LogUtil.v("LoginHandler", "COAP PARSER报错!!e=" + e.getLocalizedMessage());
hasAnalyseLen = hasAnalyseLen + singleLength + HEADLEN; //更新index值
continue; //异常的话调到下一层循环
}
operateMessage(msg); //逐个处理数据
hasAnalyseLen = hasAnalyseLen + singleLength + HEADLEN; //更新index值
}
}
//处理消息
private synchronized void operateMessage(EmptyMessage msg) {
String url = null;
try {
url = msg.getOptions().getUriPath().get(0);
} catch (Exception e) {
// e.printStackTrace();
// LogUtil.v("LoginHandler", "pingmsg.e=" + e.getLocalizedMessage());
}
if (url != null) { //非ping消息
LogUtil.v("LoginHandler", "pingmsg.toString()11=" + new Gson().toJson(msg));
}
//根据URI类型判断
if (url == null) { //ping类型
if (msg.getType() == CoAP.Type.CON) {
//todo 需要回一个ping ack消息 需要回一个ping
} else if (msg.getType() == CoAP.Type.ACK) {
//不用处理
}
} else if (url.equals("f")) { //FunctionCall类型
//todo 需要返回一个"FunctionReturn": { code: Message.Code.CHANGED, type: Message.Type.NON },
// 或者 FunctionReturnError": { code: Message.Code.BAD_REQUEST, type: Message.Type.NON },
String sss = new Gson().toJson(msg);
LogUtil.v("loginHandler", "收到的functioncall消息=" + sss);
// FunctionBean fbean = new Gson().fromJson(new Gson().toJson(msg),FunctionBean.class);
FunctionBeanList fbean = new Gson().fromJson(new Gson().toJson(msg), FunctionBeanList.class);
//f消息
// f:playlist
// {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4247,"options":{"if_none_match":false,"uri_path_list":["f","playlist"],"uri_query_list":["[{\"url\":\"https://console.nexnovo.mobi/api/video/screens/a3851e7f0d1db60c0b5dda027f720e3a546006b3.mp4\",\"hash\":\"d+Djq3BvCSOSuCgtdGIrqg\u003d\u003d\"},{\"url\":\"https://console.nexnovo.mobi/api/video/screens/9ec861fea274f48c55fedf5e29f2c43cd29a8a92.mp4\",\"hash\":\"jn5ygVnkeUD43oji3vlLJA\u003d\u003d\"}]"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[4],"type":"CON"}
//
// f:bash
// {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4256,"options":{"if_none_match":false,"uri_path_list":["f","bash"],"uri_query_list":["ifconfig"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[13],"type":"CON"}
//
// f:reboot
// {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4255,"options":{"if_none_match":false,"uri_path_list":["f","reboot"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[12],"type":"CON"}
//
// f:playpause
// {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4253,"options":{"if_none_match":false,"uri_path_list":["f","playpause"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[10],"type":"CON"}
String config = fbean.getOptions().getUri_path_list().get(1);
if (config.equals("playlist")) { //视频列表
String payListStr = fbean.getOptions().getUri_query_list().get(0);
ArrayList<String> list = new ArrayList<>(); //播放列表
try {
JSONArray array = new JSONArray(payListStr);
int len = array.length();
for (int i = 0; i < len; i++) {
JSONObject obj = array.getJSONObject(i);
String urlStr = obj.getString("url");
String hash = obj.getString("hash"); //用于判断下载下来的文件是否完整 MD5去比对 如果下载不完整需要重新下载
list.add(urlStr);
}
} catch (JSONException e) {
LogUtil.v("loginHandler", "JSONException--e=" + e.getLocalizedMessage());
e.printStackTrace();
}
//payload为空
// list.addAll(fbean.getOptions().getUri_query_list()); //当describer传fils0时 用这个获取
LogUtil.v("loginHandler", "收到的functioncall消息-视频信息=" + new Gson().toJson(list));
VideoUtils.getInstance(this).updateWebVideoList(list);
// sendFunctionReturn(msg.getToken());
sendFunctionReturn(msg.getToken(), "playlist");
} else if (config.equals("playpause")) { //暂停与开始
boolean ifPlaying = VideoUtils.getInstance(this).toggle();
String payload = ifPlaying ? "start" : "stop";
sendFunctionReturn(msg.getToken(), payload);
}
//wifi和config
else if (config.equals("bash")) { //wifi(uri-query="iwlist wlan0 scan | egrep .....") 和 config按钮 (uri-query="ifconfig")
sendFunctionReturn(msg.getToken(), "bash");
} else if (config.equals("reboot")) {
sendFunctionReturn(msg.getToken(), "Reboot");
} else if (config.equals("dimming")) { //屏幕亮度
// String lightValue = fbean.getOptions().ge
}
} else if (url.equals("v")) { //VariableRequest
// v消息
// v:temperature
// {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4252,"options":{"if_none_match":false,"uri_path_list":["v","temperature"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[9],"type":"CON"}
//
// v:brighness
// {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4248,"options":{"if_none_match":false,"uri_path_list":["v","brightness"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[5],"type":"CON"}
//
// v:play_state
// {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4249,"options":{"if_none_match":false,"uri_path_list":["v","play_state"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[6],"type":"CON"}
//
// v:light_sensor
// {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4250,"options":{"if_none_match":false,"uri_path_list":["v","light_sensor"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[7],"type":"CON"}
//
// v:playstate
// {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4251,"options":{"if_none_match":false,"uri_path_list":["v","playstate"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[8],"type":"CON"}
String config = msg.getOptions().getUriPath().get(1);
LogUtil.v("loginhandler", "loginhandler-v消息--config=" + config);
String payload = "";
if (config.equals("play_state")) { //返回当前的播放状态 'start':'stop';
if (VideoUtils.getInstance(this).ifPlaying()) {
payload = "start";
} else {
payload = "stop";
}
} else if (config.equals("playstate")) {
if (Utils.ifScreenOn(this)) {
payload = "true";
} else {
payload = "false";
}
} else if (config.equals("brightness")) {
float brightness = Utils.getActivityBrightness(MyApllication.activity);
payload = String.valueOf(brightness);
} else if (config.equals("temperature")) {
float temperature = MainActivity.temperature;
payload = temperature + "°C";
}
//todo 需要返回一个"VariableRequest": { code: Message.Code.CHANGED, type: Message.Type.NON },
sendVaribleReturn(++counter, msg.getToken(), payload);
} else if (url.equals("d")) {
sendDescribeReturn(++counter, msg.getToken());
}
}
private void sendVaribleReturn(int i, byte[] token, final String payload) {
VariableReturn fr = new VariableReturn();
fr.setMID(i);
fr.setToken(token);
// fr.setPayload("OK");
fr.setPayload(payload);
//hello.setPayload("hello");
//hello.setPayload("{\"orderNumber\": \"08171620573119330131\"}");
//hello.setToken("hhhhh".getBytes());
DataSerializer DataSerializer = new DataSerializer();
byte[] bb = DataSerializer.serializeRequest(fr);
LogUtil.v("loginHandler", "组装的VaribleReturn消息=" + RSAUtils.bytesToHexString(bb));
// byte[] bb=RSAUtils.hexStringToByte(spac);
// byte[] bb = reqeustBytes;
byte[] sendBytes = Encryptor.encrypt(Const.AES_KEY, Const.AES_IV_JIAMI, bb);
String spachex = RSAUtils.bytesToHexString(sendBytes);
//更新iv的值
//发送完hello 更新iv值 加密数据的前十六位byte 除了前缀0010
System.arraycopy(sendBytes, 0, Const.AES_IV_JIAMI, 0, AES_IV_LEN);
// System.arraycopy(sendBytes,0,Const.AES_IV_JIEMI,0,AES_IV_LEN);
// logger.info("spac hex String : "+spachex);
// logger.info("spac hex String lenth : "+sendBytes.length);
StringBuilder sb = new StringBuilder();
sb.append(getBeforeString(sendBytes.length)).append(spachex);
LogUtil.v("loginHandler", "发送的十六进制数据" + sb.toString());
//String s = "0010c55f3330b20d282861f81a6dbe3d92cd";
byte[] bbb = RSAUtils.hexStringToByte(sb.toString());
NettyClient.getInstance().sendMsgToServer(bbb, new ChannelFutureListener() { //3
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) { //4
Timber.d("Write auth successful");
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送sendVaribleReturn成功-payload=" + payload);
} else {
Timber.d("Write auth error");
WriteLogUtil.writeLogByThread("tcp auth error");
}
}
});
}
void sendDescribeReturn(int count, byte[] token) {
DescribeReturn fr = new DescribeReturn();
fr.setMID(count);
fr.setToken(token);
DescribeBean bean = new DescribeBean(); //d消息是有的
//v
DescribeBean.VBean vbean = new DescribeBean.VBean();
vbean.setTemperature("int32");
vbean.setPlay_state("int32");
vbean.setLight_sensor("int32");
vbean.setPlaystate("int32");
vbean.setBrightness("int32");
bean.setV(vbean);
//playpause
DescribeBean.PlaypauseBean playPauseBean = new DescribeBean.PlaypauseBean();
playPauseBean.setReturns("string");
List<String> list = new ArrayList<String>();
playPauseBean.setArgs(list);
bean.setPlaypause(playPauseBean);
//playlist
DescribeBean.PlaylistBean playListBean = new DescribeBean.PlaylistBean();
playListBean.setReturns("string");
List<DescribeBean.PlaylistBean.ArgsBean> list1 = new ArrayList<DescribeBean.PlaylistBean.ArgsBean>();
DescribeBean.PlaylistBean.ArgsBean argsBean = new DescribeBean.PlaylistBean.ArgsBean();
// argsBean.setFile0("string"); //只会收到一个视频文件
argsBean.setFiles("string"); //收到多个文件
list1.add(argsBean);
playListBean.setArgs(list1);
bean.setPlaylist(playListBean);
//xlist
DescribeBean.XlistBean xListBean = new DescribeBean.XlistBean();
xListBean.setReturns("string");
List<DescribeBean.XlistBean.ArgsBeanX> list2 = new ArrayList<DescribeBean.XlistBean.ArgsBeanX>();
DescribeBean.XlistBean.ArgsBeanX xargsBean = new DescribeBean.XlistBean.ArgsBeanX();
xargsBean.setUrl("string");
list2.add(xargsBean);
xListBean.setArgs(list2);
bean.setXlist(xListBean);
//xbrightness
DescribeBean.XbrightnessBean xBrightnessBean = new DescribeBean.XbrightnessBean();
xBrightnessBean.setReturns("string");
List<DescribeBean.XbrightnessBean.ArgsBeanXX> list3 = new ArrayList<DescribeBean.XbrightnessBean.ArgsBeanXX>();
DescribeBean.XbrightnessBean.ArgsBeanXX xXargsBean = new DescribeBean.XbrightnessBean.ArgsBeanXX();
xXargsBean.setLevel("uint16");
list3.add(xXargsBean);
xBrightnessBean.setArgs(list3);
bean.setXbrightness(xBrightnessBean);
//xstate
DescribeBean.XstateBean xStateBean = new DescribeBean.XstateBean();
xStateBean.setReturns("string");
List<DescribeBean.XstateBean.ArgsBeanXXX> list4 = new ArrayList<DescribeBean.XstateBean.ArgsBeanXXX>();
DescribeBean.XstateBean.ArgsBeanXXX xxxArgsBean = new DescribeBean.XstateBean.ArgsBeanXXX();
xxxArgsBean.setState("string");
list4.add(xxxArgsBean);
xStateBean.setArgs(list4);
bean.setXstate(xStateBean);
//reboot
DescribeBean.RebootBean rebootBean = new DescribeBean.RebootBean();
List<String> list10 = new ArrayList<String>();
rebootBean.setArgs(list10);
rebootBean.setReturns("string");
bean.setReboot(rebootBean);
//bash
DescribeBean.BashBean bashBean = new DescribeBean.BashBean();
bashBean.setReturns("string");
List<DescribeBean.BashBean.ArgsBeanXXXX> list6 = new ArrayList<DescribeBean.BashBean.ArgsBeanXXXX>();
DescribeBean.BashBean.ArgsBeanXXXX xxxxArgsBean = new DescribeBean.BashBean.ArgsBeanXXXX();
xxxxArgsBean.setCommand("string");
list6.add(xxxxArgsBean);
bashBean.setArgs(list6);
bean.setBash(bashBean);
String payload = new Gson().toJson(bean);
// LogUtil.v("loginHandler", "DescribeReturnPayload=" + payload);
// String test = "{\"v\":{\"temperature\":\"int32\",\"play_state\":\"int32\",\"light_sensor\":\"int32\",\"playstate\":\"int32\",\"brightness\":\"int32\"},\"playpause\":{\"returns\":\"string\",\"args\":[]},\"playlist\":{\"returns\":\"string\",\"args\":[{\"file0\":\"string\"}]},\"xlist\":{\"returns\":\"string\",\"args\":[{\"url\":\"string\"}]},\"xbrightness\":{\"returns\":\"string\",\"args\":[{\"level\":\"uint16\"}]},\"xstate\":{\"returns\":\"string\",\"args\":[{\"state\":\"string\"}]},\"reboot\":{\"returns\":\"string\",\"args\":[]},\"bash\":{\"returns\":\"string\",\"args\":[{\"command\":\"string\"}]}}";
String test = "{\"v\":{\"temperature\":\"int32\",\"play_state\":\"int32\",\"light_sensor\":\"int32\",\"playstate\":\"int32\",\"brightness\":\"int32\"}," +
"\"playpause\":{\"returns\":\"string\",\"args\":[]},\"playlist\":{\"returns\":\"string\",\"args\":[{\"file0\":\"string\"}]},\"xlist\":{\"returns\":\"string\",\"args\":[{\"url\":\"string\"}]},\"xbrightness\":{\"returns\":\"string\",\"args\":[{\"level\":\"uint16\"}]},\"xstate\":{\"returns\":\"string\",\"args\":[{\"state\":\"string\"}]},\"reboot\":{\"returns\":\"string\",\"args\":[]},\"bash\":{\"returns\":\"string\",\"args\":[{\"command\":\"string\"}]}}";
LogUtil.v("loginHandler", "DescribeReturn--test=" + test);
LogUtil.v("loginHandler", "DescribeReturn--payload=" + payload);
// fr.setPayload(test);
fr.setPayload(payload);
//hello.setPayload("hello");
//hello.setPayload("{\"orderNumber\": \"08171620573119330131\"}");
//hello.setToken("hhhhh".getBytes());
DataSerializer DataSerializer = new DataSerializer();
byte[] bb = DataSerializer.serializeRequest(fr);
LogUtil.v("loginHandler", "DescribeReturn=" + RSAUtils.bytesToHexString(bb));
LogUtil.v("loginHandler", "Const.AES_KEY=" + RSAUtils.bytesToHexString(Const.AES_KEY) + "--IV=" + RSAUtils.bytesToHexString(Const.AES_IV_JIAMI));
// byte[] bb=RSAUtils.hexStringToByte(spac);
// byte[] bb = reqeustBytes;
byte[] sendBytes = Encryptor.encrypt(Const.AES_KEY, Const.AES_IV_JIAMI, bb);
String spachex = RSAUtils.bytesToHexString(sendBytes);
LogUtil.v("loginHandler", "Descri加密后长度=" + sendBytes.length);
//更新哪个iv的值勒 RSAUTILS
//发送完hello 更新iv值 加密数据的前十六位byte 除了前缀0010
System.arraycopy(sendBytes, 0, Const.AES_IV_JIAMI, 0, AES_IV_LEN);
// System.arraycopy(sendBytes,0,Const.AES_IV_JIEMI,0,AES_IV_LEN);
// logger.info("spac hex String : "+spachex);
// logger.info("spac hex String lenth : "+sendBytes.length);
StringBuilder sb = new StringBuilder();
sb.append(getBeforeString(sendBytes.length)).append(spachex);
LogUtil.v("loginHandler", "发送的十六进制数据" + sb.toString());
//String s = "0010c55f3330b20d282861f81a6dbe3d92cd";
byte[] bbb = RSAUtils.hexStringToByte(sb.toString());
NettyClient.getInstance().sendMsgToServer(bbb, new ChannelFutureListener() { //3
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) { //4
Timber.d("Write auth successful");
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送sendDescribeReturn成功");
} else {
Timber.d("Write auth error");
WriteLogUtil.writeLogByThread("tcp auth error");
}
}
});
}
//通过长度拼接00X0
static String getBeforeString(int len) {
byte[] b = new byte[2];
byte b0 = (byte) (len >>> 8);
byte b1 = (byte) (len & 255);
b[0] = b0;
b[1] = b1;
return RSAUtils.bytesToHexString(b);
}
/**
* 十六进制字符串转int
*
* @param bs
* @return
*/
int getLenByHexString(byte[] bs) {
// int len = ((bs[0] << 8) + bs[1]);
// LogUtil.v("loginhandler","len="+len);
// return len;
return Integer.valueOf(RSAUtils.bytesToHexString(bs), 16);
}
// public static void main(String[] args){
//
// System.out.println(getBeforeString(1));
// System.out.println(getBeforeString(2));
// System.out.println(getBeforeString(16));
// System.out.println(getBeforeString(48));
//
// }
void sendFunctionReturn(byte[] token, final String payload) {
FunctionReturn fr = new FunctionReturn();
fr.setMID(++counter);
fr.setToken(token);
// fr.setPayload("OK");
fr.setPayload(payload);
//hello.setPayload("hello");
//hello.setPayload("{\"orderNumber\": \"08171620573119330131\"}");
//hello.setToken("hhhhh".getBytes());
DataSerializer DataSerializer = new DataSerializer();
byte[] bb = DataSerializer.serializeRequest(fr);
LogUtil.v("loginHandler", "组装的FunctionReturn消息=" + RSAUtils.bytesToHexString(bb));
// byte[] bb=RSAUtils.hexStringToByte(spac);
// byte[] bb = reqeustBytes;
byte[] sendBytes = Encryptor.encrypt(Const.AES_KEY, Const.AES_IV_JIAMI, bb);
String spachex = RSAUtils.bytesToHexString(sendBytes);
//更新哪个iv的值
//发送完hello 更新iv值 加密数据的前十六位byte 除了前缀0010
System.arraycopy(sendBytes, 0, Const.AES_IV_JIAMI, 0, AES_IV_LEN);
// System.arraycopy(sendBytes,0,Const.AES_IV_JIEMI,0,AES_IV_LEN);
// logger.info("spac hex String : "+spachex);
// logger.info("spac hex String lenth : "+sendBytes.length);
StringBuilder sb = new StringBuilder();
sb.append(getBeforeString(sendBytes.length)).append(spachex);
LogUtil.v("loginHandler", "发送的十六进制数据" + sb.toString());
//String s = "0010c55f3330b20d282861f81a6dbe3d92cd";
byte[] bbb = RSAUtils.hexStringToByte(sb.toString());
NettyClient.getInstance().sendMsgToServer(bbb, new ChannelFutureListener() { //3
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) { //4
Timber.d("Write auth successful");
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送sendFunctionReturn成功--payload=" + payload);
} else {
Timber.d("Write auth error");
WriteLogUtil.writeLogByThread("tcp auth error");
}
}
});
}
DataParser dataParser = new DataParser();
//解析hello消息
private void anylisedHelloMes(byte[] byteBuf) {
LogUtil.v("LoginHandler", "收到的hellobyte-=" + new Gson().toJson(byteBuf));
byte[] bb1 = new byte[byteBuf.length - 2];
System.arraycopy(byteBuf, 2, bb1, 0, byteBuf.length - 2);
// sendBrodcast(NettyService.this, UPDATE_TXT_MES, "长度="+(byteBuf.length - 2)+" 收到的hello消息="+ RSAUtils.bytesToHexString(byteBuf));
byte[] decryptBs = Encryptor.decrypt(Const.AES_KEY, Const.AES_IV_JIEMI, bb1);
// LogUtil.v("LoginHandler", "解密hello数据-decryptBs=" + RSAUtils.bytesToHexString(decryptBs));
//更新解密iv 不管iv放在前面还是后面 都无法正常解析hello消息
System.arraycopy(byteBuf, 2, Const.AES_IV_JIEMI, 0, AES_IV_LEN);
// sendBrodcast(NettyService.this, UPDATE_TXT_MES, "解密的hello消息="+ RSAUtils.bytesToHexString(decryptBs));
//接收hello消息
// EmptyMessage hellomsg =dataParser.parseMessage(decryptBs);
// System.out.println(hellomsg.toString());
// LogUtil.v("LoginHandler","解析出来的hello消息="+ new Gson().toJson(hellomsg));
// sendBrodcast(NettyService.this, UPDATE_TXT_MES, "解析出来的hello消息="+ new Gson().toJson(hellomsg));
//解密后更换iv的值(3-18位) 用解密前的数据 这里更新的话 发过去的心跳消息就不能被解析
//开启定时器
openHeartSend();
}
//发送心跳消息
private void openHeartSend() {
// 自定义心跳,每隔自定义时间向服务器发送心跳包
mScheduledExecutorService = Executors.newScheduledThreadPool(1);
// mScheduledExecutorService.scheduleAtFixedRate()
mScheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
LogUtil.v("LoginHandler", "发送心跳信息");
// //封装心跳信息
// String heartString = "41004f3e02";
// StringBuffer sbff = new StringBuffer(heartString);
// sbff.append("0010");
// byte [] bs = RSAUtils.hexStringToByte(sbff.toString()) ;
// byte[] sendBs = Encryptor.decrypt(Const.AES_KEY,Const.AES_IV_JIAMI,bs);
//
// //更新IV
// System.arraycopy(sendBs,2,Const.AES_IV_JIAMI,0,AES_IV_LEN);
Ping ping = new Ping();
ping.setMID(++counter);
DataSerializer DataSerializer = new DataSerializer();
byte[] bb = DataSerializer.serializeRequest(ping);
LogUtil.v("LoginHandler", "发送心跳信息组装=" + RSAUtils.bytesToHexString(bb));
// String spac = "41004f3e02";
// byte[] bb=RSAUtils.hexStringToByte(spac);
byte[] sendBytes = Encryptor.encrypt(Const.AES_KEY, Const.AES_IV_JIAMI, bb);
LogUtil.v("LoginHandler", "发送心跳信息2222");
String spachex = RSAUtils.bytesToHexString(sendBytes);
//发送完hello 更新iv值 加完密的数据的前十六位byte 除了前缀0010
System.arraycopy(sendBytes, 0, Const.AES_IV_JIAMI, 0, AES_IV_LEN);
StringBuilder sb = new StringBuilder();
sb.append(getBeforeString(sendBytes.length)).append(spachex);
LogUtil.v("loginHandler", "发送的十六进制数据" + sb.toString());
byte[] sendBs = RSAUtils.hexStringToByte(sb.toString());
NettyClient.getInstance().sendMsgToServer(sendBs, new ChannelFutureListener() { //3
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) { //4
Timber.d("Write heartbeat successful");
LogUtil.v("LoginHandler", "发送心跳成功");
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送心跳成功");
} else {
LogUtil.v("LoginHandler", "发送心跳信息失败");
Timber.e("Write heartbeat error");
WriteLogUtil.writeLogByThread("heartbeat error");
}
}
});
}
}, 25, 25, TimeUnit.SECONDS);
}
//第二次握手 获取签名信息
void secondHand(byte[] byteBuf) {
final int len1 = 128;
final int len2 = 256;
byte byte1[] = new byte[len1];
System.arraycopy(byteBuf, 0, byte1, 0, len1);
try {
Const.DEVICE_PUBLIC_KEY = Utils.getConfigProperties(this).getProperty("devicePrivateKeyPck8");
LogUtil.v("loginHandler", "Const.DEVICE_PRIVATE_KEY_PCK8=" + Const.DEVICE_PRIVATE_KEY_PCK8.length());
RSAPrivateKey privateKey = RSAUtils.getPrivateKey(Const.DEVICE_PRIVATE_KEY_PCK8);
//保存sessionId
// Const.SESSION_ID = RSAUtils.privateDecrypt(byte1,privateKey);
System.arraycopy(RSAUtils.privateDecrypt(byte1, privateKey), 0, Const.SESSION_ID, 0, SESSION_LEN);
System.arraycopy(RSAUtils.privateDecrypt(byte1, privateKey), 0, Const.AES_KEY, 0, AES_KEY_LEN);
System.arraycopy(RSAUtils.privateDecrypt(byte1, privateKey), AES_KEY_LEN, Const.AES_IV_JIAMI, 0, AES_IV_LEN);
// System.arraycopy(RSAUtils.privateDecrypt(byte1,privateKey),AES_KEY_LEN,Const.AES_IV_JIEMI,0,AES_IV_LEN);
LogUtil.v("loginHandler", "解密STRING=" + RSAUtils.bytesToHexString(Const.SESSION_ID));
} catch (Exception e) {
LogUtil.v("loginHandler", "解密STRING--E==" + e.getLocalizedMessage());
e.printStackTrace();
}
Const.SIGNATURE_MES = new byte[len2];
System.arraycopy(byteBuf, len1, Const.SIGNATURE_MES, 0, len2); //直接把签名信息保存到全局变量里
try {
coapConnect("hello");
} catch (Exception e) {
LogUtil.v("loginHandler", "coapConnect-E==" + e.getLocalizedMessage());
e.printStackTrace();
}
}
//发送hello消息
void coapConnect(String mes) throws Exception {
String uriStr = "coap+tcp://" + Const.HOST + ":" + Const.TCP_PORT;
// if(coapClient == null){
// LogUtil.v("loginHandler","coapConnect-uriStr=="+uriStr);
// coapClient = new CoapClient();
// }
//
Request request = new Request(CoAP.Code.POST);
Token token = new Token();
request.setToken(token);
//
// coapClient.setURI(String.valueOf(new URI(uriStr+"/h")));
coapClient
// CoapResponse response = coapClient.post("hello",0);
// LogUtil.v("loginHandler","coapConnect-coapClient=response="+new Gson().toJson(response));
// TcpDataSerializer tsz = new TcpDataSerializer();
// byte[] reqeustBytes = tsz.getByteArray(request);
// 8602313233343536b168ff48656c6c6f //生成的requestString有三十二位
// MessageDataSerialzer tsz = new MessageDataSerialzer();
// byte[] reqeustBytes = tsz.getByteArray(request); //这个格式生成的位数有十六位 b168ff48656c6c6f //等于没有生成头哦
// byte[] reqeustBytes = MessageDataSerialzer.serializeOptionsAndPayload(request);
// LogUtil.v("loginHandler","requestToByteStringMes="+RSAUtils.bytesToHexString(reqeustBytes));
// String spac ="510233a901b168"; //老外提供的原始数据
Hello hello = new Hello();
hello.setMID(counter);
//hello.setPayload("hello");
//hello.setPayload("{\"orderNumber\": \"08171620573119330131\"}");
//hello.setToken("hhhhh".getBytes());
DataSerializer DataSerializer = new DataSerializer();
byte[] bb = DataSerializer.serializeRequest(hello);
LogUtil.v("loginHandler", "组装的hello消息=" + RSAUtils.bytesToHexString(bb));
// byte[] bb=RSAUtils.hexStringToByte(spac);
// byte[] bb = reqeustBytes;
byte[] sendBytes = Encryptor.encrypt(Const.AES_KEY, Const.AES_IV_JIAMI, bb);
String spachex = RSAUtils.bytesToHexString(sendBytes);
//更新哪个iv的值勒 RSAUTILS
//发送完hello 更新iv值 加密数据的前十六位byte 除了前缀0010
System.arraycopy(sendBytes, 0, Const.AES_IV_JIAMI, 0, AES_IV_LEN);
// System.arraycopy(sendBytes,0,Const.AES_IV_JIEMI,0,AES_IV_LEN);
// logger.info("spac hex String : "+spachex);
// logger.info("spac hex String lenth : "+sendBytes.length);
StringBuilder sb = new StringBuilder();
sb.append(getBeforeString(sendBytes.length)).append(spachex);
LogUtil.v("loginHandler", "发送的十六进制数据" + sb.toString());
//String s = "0010c55f3330b20d282861f81a6dbe3d92cd";
byte[] bbb = RSAUtils.hexStringToByte(sb.toString());
NettyClient.getInstance().sendMsgToServer(bbb, new ChannelFutureListener() { //3
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) { //4
Timber.d("Write auth successful");
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送hello成功");
} else {
Timber.d("Write auth error");
WriteLogUtil.writeLogByThread("tcp auth error");
}
}
});
}
//第一次握手 发送验证消息 及本地的密钥和设备信息
void validate(byte[] byteBuf) {
byte[] rsaDeviceBytes = null;
try {
// KeyPair pair = RSAUtil.getKeyPair();
// String privateKey = RSAUtil.getPrivateKey(pair);
// String publicKey = RSAUtil.getPublicKey(pair);
// //本地保存公钥和密钥
// rsaDeviceBytes = RSAUtil.getPublicKeyBeforeBase64(pair);
// BASE64Decoder decoder = new BASE64Decoder();
Const.DEVICE_PUBLIC_KEY = Utils.getConfigProperties(this).getProperty("devicePublicKey");
LogUtil.v("LoginHandler", "Const.DEVICE_PUBLIC_KEY.length=" + Const.DEVICE_PUBLIC_KEY.length());
byte bytes[] = RSAUtils.base642Byte(Const.DEVICE_PUBLIC_KEY);
LogUtil.v("LoginHandler", "bytes.length=" + bytes.length);
rsaDeviceBytes = bytes;
} catch (Exception e) {
LogUtil.v("LoginHandler", "Exception=e:" + e.getLocalizedMessage());
e.printStackTrace();
}
//发送认证的字符串
byte bytes[] = new byte[VALIDATE_LEN + DEVICEID_LEN + RSA_PUBLICKEY_LEN];
System.arraycopy(byteBuf, 0, bytes, 0, VALIDATE_LEN); //123456789012//模拟deviceId
System.arraycopy("939030010983".getBytes(), 0, bytes, VALIDATE_LEN, DEVICEID_LEN); //123456789012//模拟deviceId
System.arraycopy(rsaDeviceBytes, 0, bytes, VALIDATE_LEN + DEVICEID_LEN, RSA_PUBLICKEY_LEN);
//加密
byte[] sendBytes = null;
RSAPublicKey publicKey = null;
// sendBrodcast(this,UPDATE_TXT_MES, "加密前的串:"+Utils.bytesToHexString(bytes));
//从配置文件里读取服务端公钥
Const.SERVER_PUBLIC_KEY_DEBUG = Utils.getConfigProperties(this).getProperty("serverPublicKeyDebug");
// LogUtil.v("LoginHandler", "读取的配置文件内容:" + Const.SERVER_PUBLIC_KEY_DEBUG);
try {
// publicKey = RSAUtils.getPublicKey(Const.SERVER_PUBLIC_KEY); //5680
publicKey = RSAUtils.getPublicKey(Const.SERVER_PUBLIC_KEY_DEBUG); //5666
//如何没有收到心跳消息咋整
sendBytes = RSAUtils.publicEncrypt(bytes, publicKey);
LogUtil.v("LoginHandler", "加密后的串:" + Utils.bytesToHexString(sendBytes));
// sendBrodcast(this,UPDATE_TXT_MES, "加密后的串:"+Utils.bytesToHexString(sendBytes));
} catch (Exception e) {
LogUtil.v("LoginHandler", "e" + e.getLocalizedMessage());
e.printStackTrace();
sendBrodcast(this, UPDATE_TXT_MES, "加密异常:" + e.getLocalizedMessage());
return;
}
NettyClient.getInstance().sendMsgToServer(sendBytes, new ChannelFutureListener() { //3
@Override
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) { //4
Timber.d("Write auth successful");
sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送认证信息成功");
} else {
Timber.d("Write auth error");
WriteLogUtil.writeLogByThread("tcp auth error");
}
}
});
}
Producer producer;
Consumer consumer;
private void connect() {
if (!NettyClient.getInstance().getConnectStatus()) {
NettyClient.getInstance().connect();//连接服务器
}
if(ifUseProducerAndConsumer) {
//创建大小为50的 BlockingQueue
BlockingQueue<EmptyMessage> queue = new ArrayBlockingQueue<>(50);
producer = new Producer(queue);
consumer = new Consumer(queue);
//开启 producer线程向队列中生产消息
new Thread(producer).start();
//开启 consumer线程 中队列中消费消息
new Thread(consumer).start();
}
}
@Override
public void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
shutdown();
NettyClient.getInstance().setReconnectNum(0);
NettyClient.getInstance().disconnect();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
public class NetworkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) { // connected to the internet
if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI
|| activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
connect();
}
}
}
}
}
nettyservice
最新推荐文章于 2023-09-26 18:28:43 发布