如何在Android服务中使用Signalr [英] How to use signalr in android Service

查看:152
本文介绍了如何在Android服务中使用Signalr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了 signalr 库,为我创建的问题是,当手机进入睡眠时,它将发出连接超时错误,并且将不再连接到服务器.

I used the signalr library and the problem that is created for me is that when the phone goes to sleep it will issue a connection time out error and will no longer connect to the server.

活动中

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


        startService(new Intent(getApplicationContext(), signalRService.class));
}}

服务中

public class SignalRService extends Service {

     private static String Tag = "ServiceSignalR";
     public static HubConnection conn = null;
     private static AndroidPlatformComponent androidPlatformComponent = null;
     private Thread back;

    private static Logger logger = new Logger() {

       @Override
       public void log(String message, LogLevel level) {
           Log.d(Tag, message);
       }
    };

    private Runnable m = new Runnable() {
       @Override
       public void run() {
            pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
            final PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.PARTIAL_WAKE_LOCK), "TAG");
            wakeLock.acquire();

           wm = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
           WifiManager.WifiLock lock =  wm.createWifiLock(WifiManager.WIFI_MODE_FULL, "LockTag");
           lock.acquire();

           startSignalR();

      }
   };

  @Override
  public void onCreate() {
     super.onCreate();
     Log.d(Tag, "Start Service");
     signalRService = this;
     back = new Thread(m);
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {

       back.start();

   networkChangeReceiver = new NetworkChangeReceiver() {
          @Override
        public void onReceive(Context context, Intent intent) {
               final ConnectivityManager connMgr = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);

               final NetworkInfo wifi = connMgr
                    .getNetworkInfo(ConnectivityManager.TYPE_WIFI);

               final NetworkInfo mobile = connMgr
                    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

               if (wifi.isAvailable() || mobile.isAvailable()) {
                if (isConnected(context)) {

                    if (back != null) {
                        if (back.isInterrupted()) {
                            back = null;
                            back = new Thread(m);
                            back.start();
                        }
                    }

                }
            }
        }
    };
        NetworkChangeReceiver.registerWifiReceiver(getApplicationContext(), networkChangeReceiver);
       return START_STICKY;
  }


   @Override
   public void onDestroy() {
       if (back != null)
          back.interrupt();
       super.onDestroy();
   }

  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
      return null;
  }


   public static void startSignalR() {
    // Connect to the server

      if (androidPlatformComponent == null)
            androidPlatformComponent = new AndroidPlatformComponent();

      Platform.loadPlatformComponent(androidPlatformComponent);


       if (conn == null)
           conn = new HubConnection("http://*************/", "", true, logger);

       HubProxy proxy = conn.createHubProxy("ChatHub");
       proxy.subscribe(new Object() {
        @SuppressWarnings("unused")
        public void messageReceived(String name, String message) {
            System.out.println(name + ": " + message);
        }
    });

     conn.start();

    conn.error(new ErrorCallback() {
        @Override
        public void onError(Throwable throwable) {
            try {
                Thread.sleep(10000);
                conn = null;
                androidPlatformComponent = null;
                startSignalR();
            } catch (Exception ex) {
            }
        }
    });

    conn.received(new MessageReceivedHandler() {

        @Override
        public void onMessageReceived(JsonElement json) {
            Intent intent = new Intent("onReceiveMessage");
            intent.setAction("MessageAction");
            intent.putExtra("Message", json.toString());
            signalRService.sendBroadcast(intent);
        }
    });
   }


       @Override
       public void onTaskRemoved(Intent rootIntent) {
           if (android.os.Build.VERSION.SDK_INT >= 21) {          

               Intent restartServiceIntent = new  Intent(getApplicationContext(),
                SignalRService.class);
               restartServiceIntent.setPackage(getPackageName());

               PendingIntent restartServicePendingIntent = PendingIntent.getService(
                getApplicationContext(), 0, restartServiceIntent,
                PendingIntent.FLAG_ONE_SHOT);
               AlarmManager alarmService = (AlarmManager) getApplicationContext()
                .getSystemService(Context.ALARM_SERVICE);

              long thirtySecondsFromNow = 1000;
              alarmService.set(AlarmManager.RTC_WAKEUP, thirtySecondsFromNow, restartServicePendingIntent);

              super.onTaskRemoved(rootIntent);
       }
   }
 }

在Manifests.xml中

in Manifests.xml

<?xml version="1.0" encoding="utf-8"?>
   <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="************.signalr2">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <receiver android:name=".MyStartServiceReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>



    <service
        android:name=".SignalRService"
        android:enabled="true"
        android:exported="false"
        android:label="Sig"
        android:largeHeap="true"
        android:stopWithTask="false" />

    <receiver
        android:name=".BroadCastMessage"
        android:enabled="true">
        <intent-filter>
            <action android:name="MessageAction" />
        </intent-filter>
    </receiver>
    <receiver
        android:name=".NetworkChangeReceiver"
        android:enabled="true">
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
    </receiver>
    <receiver
        android:name=".Screen"
        android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.SCREEN_OFF" />
            <action android:name="android.intent.action.SCREEN_ON" />
        </intent-filter>
    </receiver>

</application>

在Boot BroadCast中

in Boot BroadCast

public class MyStartServiceReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    context.stopService(new Intent(context.getApplicationContext() , SignalRService.class));
        context.startService(new Intent(context.getApplicationContext(), SignalRService.class));
}
}

在邮件BroadCast中

in Message BroadCast

public class BroadCastMessage extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Log.d("Service" , "Message-----------------------------------------------------------------------");


    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("Hi")
            .setPriority(Notification.PRIORITY_MAX)
            .setCategory(Notification.CATEGORY_CALL)
            .setDefaults(Notification.FLAG_AUTO_CANCEL | Notification.DEFAULT_SOUND)
            .setContentText(intent.getStringExtra("Message") + "")
            .setAutoCancel(true)
            .setLights(Color.parseColor("red"), 2000, 1000);
    NotificationManager mNotifyMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    mNotifyMgr.notify(100, mBuilder.build());


  }
 }

在网络状态BroadCast中

in Network State BroadCast

public class NetworkChangeReceiver extends BroadcastReceiver {

private Boolean isConnected = false;

@Override
public void onReceive(final Context context, final Intent intent) {
    final ConnectivityManager connMgr = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);

    final NetworkInfo wifi = connMgr
            .getNetworkInfo(ConnectivityManager.TYPE_WIFI);

    final NetworkInfo mobile = connMgr
            .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

    if (wifi.isAvailable() || mobile.isAvailable()) {
        if (isConnected(context)) {
            try {

                context.stopService(new Intent(context , SignalRService.class));
                context.startActivity(new Intent(context , SignalRService.class));
            } catch (Exception ex) {}
        }
    } else {
           //            isConnected = false;
    }
}


public static void registerWifiReceiver(Context context, BroadcastReceiver broadcastReceiver) {
    IntentFilter filter = new IntentFilter();
    filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
    filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
    context.registerReceiver(broadcastReceiver, filter);
}

public static boolean isConnected(Context context) {

    boolean connectedState = isNetworkAvailable(context) || isWifiAvailable(context);

    return connectedState;
}

public static boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo mobileNetworkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
    return mobileNetworkInfo != null && mobileNetworkInfo.isConnected();

}

public static boolean isWifiAvailable(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo wifiNetworkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    return wifiNetworkInfo != null && wifiNetworkInfo.isConnected();
}
  }

推荐答案

是的,可以.首先,请确保您的SignalR服务正常运行,并记下令牌和集线器连接(组名),您可以通过调用这些组来订阅这些呼叫.

Yes, you can. first of all make sure your SignalR service is working fine and noted down your token and hub connection, group name from which you can subscribe those calls by invoking them.

1)开设了一个单例课程

1) Made one singleton class

public class SignalRSingleton {

private static SignalRSingleton mInstance = null;
public HubConnection mHubConnection;
public HubProxy mHubProxy;

public static SignalRSingleton getInstance(){
    if(mInstance == null)
    {
        mInstance = new SignalRSingleton();
    }
    return mInstance;
}

public void setmHubConnection()
{
    String serverUrl = "http://192.168.1.5:8089/XM/";
    //String serverUrl = "http://192.168.1.184/test";
    mHubConnection = new HubConnection(serverUrl);
}

public void setHubProxy()
{
   /* Credentials credentials = new Credentials() {
        @Override
        public void prepareRequest(Request request) {
            request.addHeader("User-Name", MainActivity.unm);
        }
    };*/

    //mHubConnection.setCredentials(credentials);
    String SERVER_HUB_CHAT = "messages";
    //String SERVER_HUB_CHAT = "Chat";
    mHubProxy = mHubConnection.createHubProxy(SERVER_HUB_CHAT);
}


/**
 * method for clients (activities)
 */
public void sendMessage(String name , String message) {

    String str = "{'RequestMessage':{'PID':'lr1','Password':'GIefhSIC5iBCnxioufbwEw == '},'RequestType':'Login'}";
    String SERVER_METHOD_SEND = "getMessage";
    //String SERVER_METHOD_SEND = "Send";
    mHubProxy.invoke(SERVER_METHOD_SEND,str);
  }
}

2)然后实施服务

public class SignalRService extends Service {
    //private HubConnection mHubConnection;
    //private HubProxy mHubProxy;
    private Handler mHandler; // to display Toast message
    private final IBinder mBinder = new LocalBinder(); // Binder given to clients
    private SignalRSingleton mInstance;
    final static String MY_ACTION = "MY_ACTION";
    public SignalRService() {

    }

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = SignalRSingleton.getInstance();
        mHandler = new Handler(Looper.getMainLooper());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int result = super.onStartCommand(intent, flags, startId);
        startSignalR();
        return result;
    }

    @Override
    public void onDestroy() {
        mInstance.mHubConnection.stop();
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Return the communication channel to the service.
        startSignalR();
        return mBinder;
    }

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        public SignalRService getService() {
            // Return this instance of SignalRService so clients can call public methods
            return SignalRService.this;
        }
    }


    /**
     * method for clients (activities)
     */


    private void startSignalR() {
        Platform.loadPlatformComponent(new AndroidPlatformComponent());
        mInstance.setmHubConnection();
        mInstance.setHubProxy();
        ClientTransport clientTransport = new ServerSentEventsTransport(mInstance.mHubConnection.getLogger());
        SignalRFuture<Void> signalRFuture = mInstance.mHubConnection.start(clientTransport);

        try {
            signalRFuture.get();
        } catch (InterruptedException | ExecutionException e) {
            Log.e("SimpleSignalR", e.toString());
            return;
        }

        mInstance.sendMessage(MainActivity.unm,"Hello All!");

        String CLIENT_METHOD_BROADAST_MESSAGE = "recievedMessage";
        //String CLIENT_METHOD_BROADAST_MESSAGE = "messageReceived";
        mInstance.mHubProxy.on(CLIENT_METHOD_BROADAST_MESSAGE,
                new SubscriptionHandler2<String,LoginInfo>() {
                    @Override
                    public void run(final String msg,final LoginInfo loginInfo) {
                        final String finalMsg = loginInfo.FullName  + "  says " + loginInfo.Password;
                    Intent intent = new Intent();
                    intent.setAction(MY_ACTION);
                    intent.putExtra("DATAPASSED", finalMsg);
                    sendBroadcast(intent);
                }
            }
            , String.class,LoginInfo.class);
    }
}

您将收到Service Hope的电话后,您会得到所需的东西.

After you will get calls from Service Hope you will get what you need.

这篇关于如何在Android服务中使用Signalr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆