我正在使用此源应用与其他设备聊天。但是如何使其像服务一样启动,这样我就可以启动前台服务。 我需要在Service中重写MainFragment和LoginActivity吗?
socket.io应用socket.io-android-chat
我已经尝试过在SocketService类中进行类似的操作,即使关闭了应用程序,我也需要在Service for App中添加其他内容以获得通知消息。
public class SocketService extends Service {
private Socket mSocket;
public static final String TAG = SocketService.class.getSimpleName();
private static final String NOTIFICATION_CHANNEL_ID_DEFAULT = "App running in background";
String GROUP_KEY_WORK_EMAIL = "com.android.example.WORK_EMAIL";
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw null;
}
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "on created", Toast.LENGTH_SHORT).show();
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setGroup(GROUP_KEY_WORK_EMAIL);
Notification notification = builder.build();
NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
// Set big text style.
builder.setStyle(bigTextStyle);
startForeground(3, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "start command", Toast.LENGTH_SHORT).show();
try {
mSocket = IO.socket(Constants.CHAT_SERVER_URL);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
mSocket.on("newMessageReceived", onNewMessage);
mSocket.connect();
return START_STICKY;
}
private Emitter.Listener onNewMessage = new Emitter.Listener() {
@Override
public void call(Object... args) {
JSONObject data = (JSONObject) args[0];
String username;
String message;
try {
username = data.getString("username");
message = data.getString("message");
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
return;
}
Log.d(TAG, "call: new message ");
setNotificationMessage(message, username);
}
};
public void setNotificationMessage(CharSequence message, CharSequence title) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentTitle(title);
builder.setContentText(message);
NotificationManagerCompat nm = NotificationManagerCompat.from(this);
nm.notify(3, builder.build());
}
}
答案 0 :(得分:2)
当您的应用程序在后台运行时,您不应使用前台服务来获取通知消息
相反,您应该使用firebase push notification
但是,如果仍然需要在前台服务中使用套接字连接
只需创建一个单例类即可处理所有套接字连接,并将其用作前台服务,如下所示
public class SocketManger {
private static SocketManger socketManger;
Socket socket;
Callback<Boolean> onConnect;
public void init(Callback<Boolean> onConnect){
this.onConnect = onConnect;
connectToSocket();
listenToPublicEvents();
}
private void connectToSocket(){
try{
IO.Options opts = new IO.Options();
//optional parameter for authentication
opts.query = "token=" + YOUR_TOKEN;
opts.forceNew = true;
opts.reconnection = true;
opts.reconnectionDelay = 1000;
socket = IO.socket(YOUR_URL, opts);
socket.connect();
}
catch(URISyntaxException e){
throw new RuntimeException(e);
}
}
private void listenToPublicEvents(){
socket.on(Socket.EVENT_CONNECT, args -> {
if(onConnect!=null)
onConnect.onResult(true);
} );
socket.on(Socket.EVENT_DISCONNECT, args ->{
if(onConnect!=null)
onConnect.onResult(false);
});
}
public void emit(String event, JSONObject data, Ack ack){
socket.emit(event, new JSONObject[]{data}, ack);
}
public void on(String event, Emitter.Listener em){
socket.on(event, em);
}
public static SocketManger getSocketManger() {
if(socketManger == null){
socketManger = new SocketManger();
}
return socketManger;
}
public boolean isConnected(){
return socket!=null && socket.connected();
}
public void onDestroy() {
onConnect = null;
socket.disconnect();
}
public interface Callback<T> {
void onResult(T t);
}
}
并将此代码添加到您的前台服务
SocketManager socketManger = SocketManger.getSocketManger();
@Override
public void onCreate() {
socketManger.init(this::onSocketEvent);
}
public void onSocketEvent(boolean connect){
//your code when the socket connection connect or disconnect
}
并确保在服务被破坏时断开套接字
@Override
public void onDestroy() {
socketManger.onDestroy()
super.onDestroy();
}
答案 1 :(得分:1)
如果希望在应用程序启动后立即启动服务,则可以从onCreate方法中的自定义Application类启动它。
或者您可以从任何活动中启动它,例如如果要从某些活动启动服务,请使用onCreate方法。
或者在启动设备时可以从BroadcastReceiver开始。在这种情况下,请使用BOOT_COMPLETED操作:
要启动服务,只需在要启动服务的任何地方使用此代码:
Intent intent = new Intent(context, SocketService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}