Send signal when wifi status change.
This commit is contained in:
parent
d0f4a82043
commit
af28ef0a3c
@ -7,10 +7,13 @@
|
||||
android:glEsVersion="0x00020000"
|
||||
android:required="true" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- For Programaker bridge -->
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
@ -5,12 +5,14 @@ import android.provider.Settings;
|
||||
|
||||
import com.codigoparallevar.minicards.ConfigManager;
|
||||
import com.codigoparallevar.minicards.bridge.blocks.DefaultAndroidBlocks;
|
||||
import com.codigoparallevar.minicards.bridge.helpers.StatusStreamer;
|
||||
import com.programaker.bridge.ProgramakerBridge;
|
||||
import com.programaker.bridge.ProgramakerBridgeConfiguration;
|
||||
|
||||
public class ProgramakerAndroidBridge {
|
||||
private static final String LogTag = "PM Android Bridge";
|
||||
private ProgramakerBridge bridgeRunner = null;
|
||||
private StatusStreamer statusStreamer = null;
|
||||
|
||||
// Static
|
||||
public static ProgramakerAndroidBridge configure(Context ctx, String userId, String bridgeId) {
|
||||
@ -43,9 +45,13 @@ public class ProgramakerAndroidBridge {
|
||||
|
||||
this.bridgeRunner = new ProgramakerBridge(this.bridgeId, this.userId, configuration, onReady, onComplete);
|
||||
this.bridgeRunner.run();
|
||||
|
||||
this.statusStreamer = new StatusStreamer(this.ctx, this.bridgeRunner);
|
||||
this.statusStreamer.run();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
bridgeRunner.stop();
|
||||
this.statusStreamer.stop();
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import com.programaker.bridge.ProgramakerBridgeConfigurationBlock;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BridgeBlockListBuilder {
|
||||
private final LinkedList<ProgramakerBridgeConfigurationBlock> blockList;
|
||||
@ -25,6 +24,18 @@ public class BridgeBlockListBuilder {
|
||||
return this.addOperation(new OperationBlockDefinition(id, message, arguments, operation));
|
||||
}
|
||||
|
||||
public BridgeBlockListBuilder addTrigger(String id, String message,
|
||||
List<BlockArgumentDefinition> arguments,
|
||||
String key) {
|
||||
return this.addTrigger(new TriggerBlockDefinition(id, message, arguments, key));
|
||||
}
|
||||
|
||||
private BridgeBlockListBuilder addTrigger(TriggerBlockDefinition block) {
|
||||
this.blockList.add(block);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private BridgeBlockListBuilder addOperation(ProgramakerBridgeConfigurationBlock block) {
|
||||
this.blockList.add(block);
|
||||
|
||||
|
@ -53,8 +53,8 @@ public class DefaultAndroidBlocks {
|
||||
notificationManager.createNotificationChannel(vibrationChannel);
|
||||
}
|
||||
|
||||
|
||||
return new BridgeBlockListBuilder()
|
||||
// OPERATIONS
|
||||
BridgeBlockListBuilder builder = new BridgeBlockListBuilder()
|
||||
// Notifications
|
||||
.addOperation(
|
||||
"notifications_new",
|
||||
@ -109,7 +109,6 @@ public class DefaultAndroidBlocks {
|
||||
pattern[i * 2] = VIBRATION_ACTIVE_TIME;
|
||||
pattern[i * 2 + 1] = VIBRATION_REST_TIME;
|
||||
}
|
||||
// pattern[0] = 0; // Start immediately
|
||||
|
||||
Notification notif = new NotificationCompat
|
||||
.Builder(ctx, ProgramakerBridgeService.BridgeUserVibrationNotificationChannel)
|
||||
@ -145,5 +144,22 @@ public class DefaultAndroidBlocks {
|
||||
}
|
||||
)
|
||||
;
|
||||
|
||||
// Signal blocks
|
||||
builder
|
||||
.addTrigger(
|
||||
"on_wifi_connected",
|
||||
"When WIFI connects",
|
||||
Collections.emptyList(),// TODO: Save content to variable
|
||||
"on_wifi_connected"
|
||||
)
|
||||
.addTrigger(
|
||||
"on_wifi_disconnected",
|
||||
"When WIFI connection is lost",
|
||||
Collections.emptyList(),
|
||||
"on_wifi_disconnected"
|
||||
);
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import org.json.JSONObject;
|
||||
import java.util.List;
|
||||
|
||||
class OperationBlockDefinition implements ProgramakerBridgeConfigurationBlock {
|
||||
private final static String LogTag = "PM OpBlockDefinition";
|
||||
private final static String LogTag = "PM OpBlockDef";
|
||||
|
||||
private final String id;
|
||||
private final String message;
|
||||
|
@ -0,0 +1,67 @@
|
||||
package com.codigoparallevar.minicards.bridge.blocks;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.programaker.bridge.ProgramakerBridgeConfigurationBlock;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class TriggerBlockDefinition implements ProgramakerBridgeConfigurationBlock {
|
||||
private final static String LogTag = "PM TriggerBlockDef";
|
||||
|
||||
private final String id;
|
||||
private final String message;
|
||||
private final List<BlockArgumentDefinition> args;
|
||||
private final String key;
|
||||
|
||||
public TriggerBlockDefinition(String id, String message, List<BlockArgumentDefinition> args,
|
||||
String key) {
|
||||
this.id = id;
|
||||
this.message = message;
|
||||
this.args = args;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JSONObject serialize() {
|
||||
JSONObject obj = new JSONObject();
|
||||
|
||||
try {
|
||||
JSONArray arguments = new JSONArray();
|
||||
for (BlockArgumentDefinition arg : this.args) {
|
||||
arguments.put(arg.serialize());
|
||||
}
|
||||
|
||||
obj.put("id", this.id);
|
||||
obj.put("function_name", this.id);
|
||||
obj.put("message", this.message);
|
||||
obj.put("arguments", arguments);
|
||||
obj.put("save_to", JSONObject.NULL);
|
||||
obj.put("expected_value", JSONObject.NULL);
|
||||
obj.put("block_type", "trigger");
|
||||
obj.put("key", this.key);
|
||||
obj.put("subkey", JSONObject.NULL);
|
||||
} catch (JSONException ex) {
|
||||
Log.e(LogTag, "Error serializing block definition: " + ex, ex);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFunctionName() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(@NotNull List<?> arguments) throws Exception {
|
||||
throw new IllegalArgumentException("Non executable block");
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.codigoparallevar.minicards.bridge.helpers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.wifi.SupplicantState;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
|
||||
import com.programaker.bridge.ProgramakerBridge;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class StatusStreamer {
|
||||
private final Context ctx;
|
||||
private final ProgramakerBridge bridge;
|
||||
private WifiNetworkCallbackReceiver networkCallback = null;
|
||||
|
||||
public StatusStreamer(Context ctx, ProgramakerBridge bridge) {
|
||||
this.ctx = ctx;
|
||||
this.bridge = bridge;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
this.networkCallback = new WifiNetworkCallbackReceiver(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkRequest.Builder builder = new NetworkRequest.Builder();
|
||||
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
|
||||
|
||||
ConnectivityManager connManager = (ConnectivityManager) this.ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
assert connManager != null;
|
||||
|
||||
connManager.registerNetworkCallback(builder.build(), this.networkCallback);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
ConnectivityManager connManager = (ConnectivityManager) this.ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
assert connManager != null;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
connManager.unregisterNetworkCallback(this.networkCallback);
|
||||
}
|
||||
}
|
||||
|
||||
public void onWifiNetworkConnected(Network network) {
|
||||
WifiManager wifiManager = (WifiManager) this.ctx.getSystemService(Context.WIFI_SERVICE);
|
||||
WifiInfo wifiInfo;
|
||||
|
||||
wifiInfo = wifiManager.getConnectionInfo();
|
||||
String ssid = "";
|
||||
if (wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
|
||||
// This might not return the SSID in case the user has not granted location permissions to the app
|
||||
// see: https://stackoverflow.com/a/54446042
|
||||
ssid = wifiInfo.getSSID();
|
||||
}
|
||||
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("ssid", ssid);
|
||||
|
||||
this.bridge.sendSignal("on_wifi_connected", new JSONObject(data));
|
||||
}
|
||||
|
||||
public void onWifiNetworkDisconnected() {
|
||||
this.bridge.sendSignal("on_wifi_disconnected", new JSONObject());
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.codigoparallevar.minicards.bridge.helpers;
|
||||
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Network;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
class WifiNetworkCallbackReceiver extends ConnectivityManager.NetworkCallback {
|
||||
private final StatusStreamer streamer;
|
||||
|
||||
public WifiNetworkCallbackReceiver(StatusStreamer statusStreamer) {
|
||||
this.streamer = statusStreamer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAvailable(Network network) {
|
||||
super.onAvailable(network);
|
||||
this.streamer.onWifiNetworkConnected(network);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnavailable() {
|
||||
super.onUnavailable();
|
||||
this.streamer.onWifiNetworkDisconnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLost(Network network) {
|
||||
super.onLost(network);
|
||||
this.streamer.onWifiNetworkDisconnected();
|
||||
}
|
||||
}
|
@ -173,4 +173,21 @@ class ProgramakerBridge(
|
||||
fun stop() {
|
||||
webSocket?.close(1000, null)
|
||||
}
|
||||
|
||||
fun sendSignal(key: String, content: JSONObject) {
|
||||
if (webSocket == null) {
|
||||
Log.w(LogTag, "Cannot send signal (key=$key) on closed channel")
|
||||
return
|
||||
}
|
||||
|
||||
webSocket!!.send(JSONObject(hashMapOf(
|
||||
"type" to "NOTIFICATION",
|
||||
"key" to key,
|
||||
"subkey" to JSONObject.NULL,
|
||||
"to_user" to JSONObject.NULL,
|
||||
"value" to content,
|
||||
"content" to content
|
||||
)
|
||||
).toString())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user