2017-02-13 57 views
3

美好的一天。考虑到针对android及其服务的Socket IO库,我有一个非常具体的问题。使用Android服务的套接字Io

重要的是要提到我的设备是我正在测试的华为p8 lite。

这里有云:

•我有一个被我创建

•我设置了监听器插座IO新消息

•里面的服务初始化套接字IO库如果应用程序没有在用户的进程中被终止,那么所有东西都可以像char一样工作。

•服务的目的是保持套接字IO连接处于活动状态,即使应用程序被终止,以便用户将收到有关新消息的通知。

•只要应用程序被杀害,该Socket IO连接已经断开

无论我怎么努力,我努力的一切可能的方式:隔离服务的过程中,给了另一个进程服务,启动它粘,启动它不粘粘一旦服务破坏等重新创建。

唯一已经工作的是startForeground()方法,但我不想使用它,因为它会去设计原则,另外我不想显示关于正在运行的服务的任何通知。

我的问题是下一个:任何人都可以帮助我,并告诉我如何保持Socket IO连接活着,即使应用程序被杀害?

这里是服务的代码。

package com.github.nkzawa.socketio.androidchat; 

import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.os.IBinder; 
import android.support.annotation.Nullable; 
import android.support.v4.app.NotificationCompat; 
import android.util.Log; 
import android.widget.Toast; 

import java.net.URISyntaxException; 

import io.socket.client.IO; 
import io.socket.client.Socket; 
import io.socket.emitter.Emitter; 

public class SocketService extends Service { 
    private Socket mSocket; 
    public static final String TAG = SocketService.class.getSimpleName(); 

    @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(); 
    } 

    @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) { 
      String message = args[0].toString(); 
      Log.d(TAG, "call: new message "); 
      sendGeneralNotification(getApplicationContext(), "1", "new message", message, null); 
     } 
    }; 

    private void sendGeneralNotification(Context context, String uniqueId, 
             String title, String contentText, 
             @Nullable Class<?> resultClass) { 

     NotificationManager notificationManagerCompat = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); 

     android.support.v7.app.NotificationCompat.Builder builder = new android.support.v7.app.NotificationCompat.Builder(context); 
     builder.setAutoCancel(true); 


     builder.setContentTitle(title); 
     builder.setContentText(contentText); 
     builder.setGroup("faskfjasfa"); 
     builder.setDefaults(android.app.Notification.DEFAULT_ALL); 
     builder.setStyle(new NotificationCompat.BigTextStyle() 
       .setSummaryText(title) 
       .setBigContentTitle(title) 
       .bigText(contentText) 
     ); 

     Intent requestsViewIntent = new Intent(context, MainActivity.class); 
     requestsViewIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP 
       | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
     requestsViewIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP 
       | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
     PendingIntent requestsViewPending = PendingIntent.getActivity(context, Integer.valueOf(uniqueId), requestsViewIntent, 0); 
     builder.setContentIntent(requestsViewPending); 
     builder.setSmallIcon(R.drawable.ic_launcher); 

     builder.setShowWhen(true); 
     android.app.Notification notification = builder.build(); 
     notificationManagerCompat.notify(Integer.valueOf(uniqueId), notification); 
    } 

    private Notification getNotification() { 
     Notification notification; 
     NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 
     builder.setColor(getResources() 
       .getColor(R.color.material_deep_teal_500)) 
       .setAutoCancel(true); 

     notification = builder.build(); 
     notification.flags = Notification.FLAG_FOREGROUND_SERVICE | Notification.FLAG_AUTO_CANCEL; 

     return notification; 
    } 
} 

也没有,我不希望使用既不火力也不做的人任何第三方因为我使用的一个,现在我从延迟苦,非收到的通知等方面,我会做出自己的小一种方式更好。感谢大家的时间和耐心。

+2

嗯我想我已经问过真正可怕的问题了吧?没有人甚至试图暗示或给出最小提示 –

+0

Hi Volo,我也遇到了完全相同的问题,你是否找到了实现它的方法,如果可以的话,你可以分享它作为你自己的答案,谢谢你提前。 –

+0

在此处查找完整的服务器和客户端解决方案https://stackoverflow.com/a/45099689/5063805 – JosephM

回答

0

对不起,没有人快速回复你的问题。我希望2018年的情人不会为了别人而受苦。

在后台实现Socket.io不是最好的想法。 Socket.io有一个活动的ping到你的服务器。短时间使用它是可以的,但在后台它是一个NO。

解决您的问题的最佳方法是结合Socket.io和FCM/GCM主题发出广播。在用户设备上,检测是否存在活动的Socket.io连接,如果退出则忽略FCM,否则执行FCM。

0

在您的服务类中实现此方法并尝试使用此方法。

@Override 
public void onTaskRemoved(Intent rootIntent) { 
    super.onTaskRemoved(rootIntent); 


Intent restartServiceIntent = new Intent(getApplicationContext(),this.getClass()); 

    restartServiceIntent.setPackage(getPackageName()); 
    restartServiceIntent.putExtra("NODE CONNECTED", true); 
    PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT); 
    AlarmManager alarmService = (AlarmManager) getApplicationContext(). 
      getSystemService(Context.ALARM_SERVICE); 
    alarmService.set(
      AlarmManager.ELAPSED_REALTIME, 
      SystemClock.elapsedRealtime() + 1000, 
      restartServicePendingIntent); 
} 

当您终止应用程序并重新启动您的后台服务时,此方法将会调用。