如何在Android Service中使用Signalr
作者:互联网
我使用了信号器库,而为我创建的问题是,当电话进入睡眠状态时,它将发出连接超时错误,并且将不再连接至服务器.
in Activity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(getApplicationContext(), signalRService.class));
}}
in Service
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 one rror(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);
}
}
}
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>
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));
}
}
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());
}
}
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服务正常运行,并记下令牌和集线器连接(组名),您可以通过调用这些组来从中订购这些呼叫.
1)参加一门单身课程
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的电话后,您将得到所需的东西.
标签:android,signalr,service,connection-timeout,sleep-mode 来源: https://codeday.me/bug/20191012/1897294.html