2017-02-13 80 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); 
} 

當您終止應用程序並重新啓動您的後臺服務時,此方法將會調用。