Files
Xuewang365OSLenovo/app/src/main/java/com/xwad/os/service/SocketService.java
tongtongstudio 3001c33bc6 version
fix:
update:去掉联想csdk获取sn
2025-12-01 10:42:22 +08:00

435 lines
16 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.xwad.os.service;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import com.blankj.utilcode.util.NetworkUtils;
import com.google.gson.JsonObject;
import com.tencent.mmkv.MMKV;
import com.xwad.os.BuildConfig;
import com.xwad.os.R;
import com.xwad.os.activity.main.MainActivity;
import com.xwad.os.config.CommonConfig;
import com.xwad.os.manager.RemoteManager;
import com.xwad.os.utils.ActivationUtil;
import com.xwad.os.utils.LenovoCsdkUtil;
import com.xwad.os.utils.Utils;
import com.xwad.os.websocket.JWebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import java.net.URI;
import java.util.concurrent.TimeUnit;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
/**
* 【有道云笔记】学生项目-用户端websocket对接.md
* https://note.youdao.com/s/Pbv87efV
* <p>
* 【有道云笔记】学生项目-设备端websocket对接.md
* https://note.youdao.com/s/Ea0tebj8
* <p>
* 【有道云笔记】学生项目-管理端websocket对接.md
* https://note.youdao.com/s/MazEq49Q
* <p>
* 老人在线websocket重构了按照这个重新对接跟之前售后差不多是一样的。
* <p>
* 1.设备未激活 不链接websocket 形成不了关联设备激活后才链接websocket
* 2.已激活的设备设备若已链接websocket用户确认绑定后断开websocket 等待5秒 再重新链接websocket 以刷新用户关联
* 3.设备用户解除绑定后断开websocket 等待5秒 再重新链接websocket 以刷新用户关联
*/
public class SocketService extends Service implements NetworkUtils.OnNetworkStatusChangedListener {
private static final String TAG = "JWebSocketClientService";
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
public JWebSocketClient mJWebSocketClient;
// private SocketServiceBinder mBinder = new SocketServiceBinder();
@Override
public void onDisconnected() {
Log.i(TAG, "网络断开连接");
}
@Override
public void onConnected(NetworkUtils.NetworkType networkType) {
Log.i(TAG, "网络已连接");
}
//用于Activity和service通讯
public class SocketServiceBinder extends Binder {
public SocketService getService() {
return SocketService.this;
}
}
// private ServiceConnection mServiceConnection = new ServiceConnection() {
// @Override
// public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
// Log.e(TAG, "onServiceConnected: componentName = " + componentName);
// boolean isServiceRunning = ServiceAliveUtils.isServiceAlive(SocketService.this, ManagerService.class.getName());
// Log.e(TAG, "onServiceConnected: isServiceRunning = " + isServiceRunning);
// if (!isServiceRunning) {
// startService(new Intent(SocketService.this, ManagerService.class));
// }
// }
//
// @Override
// public void onServiceDisconnected(ComponentName componentName) {
// Log.e(TAG, "onServiceDisconnected: ");
// // 断开链接
// startService(new Intent(SocketService.this, ManagerService.class));
// // 重新绑定
// bindService(new Intent(SocketService.this, ManagerService.class), mServiceConnection, Context.BIND_IMPORTANT);
// }
// };
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate: ");
NetworkUtils.registerNetworkStatusChangedListener(this);
registerScreenLockReceiver();
registerJxwRegisterRefreshReceiver();
if (ActivationUtil.getInstance().isActivation()) {
//初始化websocket
initSocketClient();
startLoop();
} else {
Log.e(TAG, "onCreate: 未激活不连接");
}
// boolean isServiceRunning = ServiceAliveUtils.isServiceAlive(this, MainService.class.getName());
// Log.e(TAG, "onCreate: isServiceRunning = " + isServiceRunning);
// if (!isServiceRunning) {
// startService(new Intent(this, MainService.class));
// }
// bindService(new Intent(this, ManagerService.class), mServiceConnection, Context.BIND_IMPORTANT);
mNotificationManagerCompat = NotificationManagerCompat.from(this);
createNotificationChannel();
// showNotification();
sendSimpleNotification();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand: ");
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
NetworkUtils.unregisterNetworkStatusChangedListener(this);
dispose();
closeConnect();
if (mScreenLockReceiver != null) {
unregisterReceiver(mScreenLockReceiver);
}
if (mJxwRegisterReceiver != null) {
unregisterReceiver(mJxwRegisterReceiver);
}
// unbindService(mServiceConnection);
}
private static final String CHANNEL_ID = "CHANNEL_ID";
private static final String CHANNEL_NAME = "系统通知";
private static final String CHANNEL_DESCRIPTION = "学习课堂通知";
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = CHANNEL_NAME;
String description = CHANNEL_DESCRIPTION;
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
private NotificationManagerCompat mNotificationManagerCompat;
private int NotificationID = 1;
private void sendSimpleNotification() {
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "CHANNEL_ID")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("学习课堂正在运行")
// .setContentText("测试内容")
.setAutoCancel(false)
.setShowWhen(false)
.setContentIntent(pendingIntent)
.setOngoing(true)
.setOnlyAlertOnce(true)
.setPriority(NotificationCompat.PRIORITY_MAX);
// notificationId is a unique int for each notification that you must define
// mNotificationManagerCompat.notify(NotificationID, builder.build());
startForeground(NotificationID, builder.build());
}
private ScreenLockReceiver mScreenLockReceiver;
private void registerScreenLockReceiver() {
if (null == mScreenLockReceiver) {
mScreenLockReceiver = new ScreenLockReceiver();
}
IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(Intent.ACTION_SHUTDOWN);
filter.addAction(Intent.ACTION_FACTORY_RESET);
filter.addAction(Intent.ACTION_MASTER_CLEAR);
registerReceiver(mScreenLockReceiver, filter);
}
private class ScreenLockReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.e(TAG, "onReceive:" + action);
if (TextUtils.isEmpty(action)) {
Log.e(TAG, "onReceive: is NULL");
return;
}
switch (action) {
case Intent.ACTION_BOOT_COMPLETED:
case Intent.ACTION_USER_PRESENT:
case Intent.ACTION_SCREEN_ON:
sendMsgScreen();
break;
case Intent.ACTION_SCREEN_OFF:
case Intent.ACTION_SHUTDOWN:
case Intent.ACTION_FACTORY_RESET:
case Intent.ACTION_MASTER_CLEAR:
sendMsgScreen();
break;
default:
break;
}
}
}
public static final String JXW_REGISTER_SUCCESS = "com.zzj.regist_success";
private JxwRegisterReceiver mJxwRegisterReceiver;
private void registerJxwRegisterRefreshReceiver() {
if (mJxwRegisterReceiver == null) {
mJxwRegisterReceiver = new JxwRegisterReceiver();
}
IntentFilter filter = new IntentFilter();
filter.addAction(JXW_REGISTER_SUCCESS);
registerReceiver(mJxwRegisterReceiver, filter);
}
public class JxwRegisterReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.e("JxwRegisterReceiver", "onReceive: " + action);
if (JXW_REGISTER_SUCCESS.equals(action)) {
mMMKV.encode(JXW_REGISTER_SUCCESS, true);
mMMKV.encode(CommonConfig.UIUI_ACTIVATION_KEY, ActivationUtil.getInstance().ACTIVATED_KEY);
initSocketClient();
startLoop();
}
}
}
private Disposable mDisposable;
private void dispose() {
if (mDisposable != null && !mDisposable.isDisposed()) {
mDisposable.dispose();
mDisposable = null;
}
}
private void startLoop() {
if (mDisposable != null && !mDisposable.isDisposed()) {
mDisposable.dispose();
mDisposable = null;
}
mDisposable = Observable.interval(30, TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long s) throws Exception {
Log.d(TAG, "startLoop accept: " + s);
Log.i(TAG, "心跳包检测websocket连接状态");
if (!ActivationUtil.getInstance().isActivation()) {
dispose();
}
//每隔一定的时间,对长连接进行一次心跳检测
if (Utils.isScreenOn(SocketService.this)) {
if (mJWebSocketClient != null) {
if (mJWebSocketClient.isOpen()) {
Log.i(TAG, "websocket已连接");
sendPingMsg();
} else if (mJWebSocketClient.isClosed()) {
Log.i(TAG, "websocket重连中");
reconnectWs();
}
} else {
//如果client已为空重新初始化连接
initSocketClient();
}
} else {
Log.i(TAG, "websocket息屏不重连");
}
}
});
}
/**
* 初始化websocket连接
*/
private void initSocketClient() {
URI uri = URI.create(BuildConfig.WEBSOCKET_URL + "?sn=" + RemoteManager.getInstance().getSerial());
mJWebSocketClient = new JWebSocketClient(uri) {
@Override
public void onMessage(String message) {
Log.i(TAG, "onMessage: 收到服务器发来的消息:" + message);
}
@Override
public void onOpen(ServerHandshake handshakedata) {
super.onOpen(handshakedata);
Log.i(TAG, "onOpen: websocket连接成功");
sendPingMsg();
}
@Override
public void onClose(int code, String reason, boolean remote) {
super.onClose(code, reason, remote);
Log.e(TAG, "onClose: websocket连接关闭:" + reason);
mJWebSocketClient = null;
}
@Override
public void onError(Exception ex) {
super.onError(ex);
Log.e(TAG, "onError: websocket连接错误:" + ex.getMessage());
mJWebSocketClient = null;
}
};
connect();
}
/**
* 连接websocket
*/
private void connect() {
try {
//connectBlocking多出一个等待操作会先连接再发送否则未连接发送会报错
Log.i(TAG, "connect: websocket连接中");
mJWebSocketClient.connectBlocking();
} catch (Exception e) {
Log.i(TAG, "connect: " + e.getMessage());
}
}
/**
* 开启重连
*/
private void reconnectWs() {
Log.e(TAG, "reconnectWs: ");
try {
Log.i(TAG, "reconnectWs: 开启重连");
mJWebSocketClient.reconnectBlocking();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 断开连接
*/
private void closeConnect() {
Log.e(TAG, "closeConnect: ");
try {
if (null != mJWebSocketClient) {
mJWebSocketClient.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
mJWebSocketClient = null;
}
}
/**
* 发送消息
*/
public void sendPingMsg() {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("sn", RemoteManager.getInstance().getSerial());
jsonObject.addProperty("type", "ping");
if (null != mJWebSocketClient) {
Log.i(TAG, "sendPingMsg: 发送的消息:" + jsonObject.toString());
mJWebSocketClient.send(jsonObject.toString());
}
}
public void sendMsgScreen() {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("sn", RemoteManager.getInstance().getSerial());
if (Utils.isScreenOn(SocketService.this)) {
jsonObject.addProperty("type", "device_open_screen");
} else {
jsonObject.addProperty("type", "device_close_screen");
//熄屏状态
}
if (null != mJWebSocketClient) {
Log.i(TAG, "sendMsgScreen 发送的消息" + jsonObject.toString());
try {
mJWebSocketClient.send(jsonObject.toString());
} catch (Exception e) {
Log.i(TAG, "sendMsgScreen: sendMsg Exception: " + e.getLocalizedMessage());
}
} else {
Log.i(TAG, "sendMsgScreen: 未连接");
initSocketClient();
}
}
}