2017-02-13 2 views
3

おはよう。私はアンドロイドのためのソケットIOライブラリとそれがサービスだと考えると、非常に特定の問題があります。ソケットサービスのAndroidサービス

私のデバイスは、私がテストしているhuawei p8 liteです。

ここでは、行く:

私は新しいメッセージ

用ソケットIOにリスナーを設定します私は

を作成しているサービスの内部で初期化されているソケットイオライブラリを持っています•アプリケーションがプロセスtrey内でユーザーによって強制終了されない場合、すべてがcharのように機能します。

•サービスの目的は、アプリケーションが強制終了されても、ユーザーに新しいメッセージが通知されるようにしても、ソケットIO接続を有効に保つことでした。

とすぐにアプリケーションが殺されているように、ソケットIO接続がどんなに私がしようとするもの

を切断されていない、と私は可能な方法をすべて試してください。•のための別の加工を施し、サービスのプロセスを分離サービスが壊れてしまって、サービスが破棄されたら直ちに再作成するようにしてください。

唯一効果があったのはstartForeground()メソッドですが、使用する必要はありません設計の原則とプラス私は実行中のサービスについての通知を表示したくない。

私の質問は次のとおりです。誰かが私を助けて、アプリケーションが強制終了されてもソケット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; 
    } 
} 

そしてNO、私は今1を使用していると私は遅れに苦しむとして未受信通知となどから、firebaseも任意のサードパーティが行わどちらのものを使用したくない、と私は私自身のようになります小さい方が良い。皆さん、ありがとうございました。

+2

私は本当に恐ろしい質問をしたのでしょうか?誰ももっと近くに座ってみたり、最小のヒントを与えようとしたことはありません –

+0

こんにちは、まったく同じ問題に直面しています。それを実現する方法はありましたか? –

+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); 
} 

このメソッドは、アプリケーションを終了してバックグラウンドサービスを再開するときに呼び出されます。