如何在Android服务中使用Signalr [英] How to use signalr in android Service
问题描述
我使用了 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屋!